Line data Source code
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 : Copyright (C) Guenther Deschner 2009-2011,2013
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program. If not, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "torture/torture.h"
26 : #include "librpc/gen_ndr/ndr_misc.h"
27 : #include "librpc/gen_ndr/ndr_spoolss.h"
28 : #include "librpc/gen_ndr/ndr_spoolss_c.h"
29 : #include "librpc/gen_ndr/ndr_winreg_c.h"
30 : #include "librpc/gen_ndr/ndr_security.h"
31 : #include "libcli/security/security.h"
32 : #include "torture/rpc/torture_rpc.h"
33 : #include "param/param.h"
34 : #include "lib/registry/registry.h"
35 : #include "libcli/libcli.h"
36 : #include "libcli/raw/raw_proto.h"
37 : #include "libcli/resolve/resolve.h"
38 : #include "libcli/smb2/smb2.h"
39 : #include "libcli/smb2/smb2_calls.h"
40 : #include "lib/cmdline/cmdline.h"
41 : #include "system/filesys.h"
42 : #include "torture/ndr/ndr.h"
43 : #include "torture/smb2/proto.h"
44 :
45 : #define TORTURE_WELLKNOWN_PRINTER "torture_wkn_printer"
46 : #define TORTURE_PRINTER "torture_printer"
47 : #define TORTURE_WELLKNOWN_PRINTER_EX "torture_wkn_printer_ex"
48 : #define TORTURE_PRINTER_EX "torture_printer_ex"
49 : #define TORTURE_DRIVER "torture_driver"
50 : #define TORTURE_DRIVER_ADD "torture_driver_add"
51 : #define TORTURE_DRIVER_EX "torture_driver_ex"
52 : #define TORTURE_DRIVER_ADOBE "torture_driver_adobe"
53 : #define TORTURE_DRIVER_EX_ADOBE "torture_driver_ex_adobe"
54 : #define TORTURE_DRIVER_ADOBE_CUPSADDSMB "torture_driver_adobe_cupsaddsmb"
55 : #define TORTURE_DRIVER_TIMESTAMPS "torture_driver_timestamps"
56 : #define TORTURE_DRIVER_DELETER "torture_driver_deleter"
57 : #define TORTURE_DRIVER_COPY_DIR "torture_driver_copy_from_directory"
58 : #define TORTURE_DRIVER_DELETERIN "torture_driver_deleterin"
59 : #define TORTURE_PRINTER_STATIC1 "print1"
60 :
61 : #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
62 : #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
63 : #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
64 : #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
65 : #define TOP_LEVEL_CONTROL_PRINTERS_KEY TOP_LEVEL_CONTROL_KEY "\\Printers"
66 : #define TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY TOP_LEVEL_CONTROL_KEY "\\Environments"
67 :
68 : struct test_spoolss_context {
69 : struct dcerpc_pipe *spoolss_pipe;
70 :
71 : /* server environment */
72 : const char *environment;
73 :
74 : /* print server handle */
75 : struct policy_handle server_handle;
76 :
77 : /* for EnumPorts */
78 : uint32_t port_count[3];
79 : union spoolss_PortInfo *ports[3];
80 :
81 : /* for EnumPrinterDrivers */
82 : uint32_t driver_count[9];
83 : union spoolss_DriverInfo *drivers[9];
84 :
85 : /* for EnumMonitors */
86 : uint32_t monitor_count[3];
87 : union spoolss_MonitorInfo *monitors[3];
88 :
89 : /* for EnumPrintProcessors */
90 : uint32_t print_processor_count[2];
91 : union spoolss_PrintProcessorInfo *print_processors[2];
92 :
93 : /* for EnumPrinters */
94 : uint32_t printer_count[6];
95 : union spoolss_PrinterInfo *printers[6];
96 : };
97 :
98 : struct torture_driver_context {
99 : struct {
100 : const char *driver_directory;
101 : const char *environment;
102 : } local;
103 : struct {
104 : const char *driver_directory;
105 : const char *driver_upload_directory;
106 : const char *environment;
107 : } remote;
108 : struct spoolss_AddDriverInfo8 info8;
109 : bool ex;
110 : };
111 :
112 : struct torture_printer_context {
113 : struct dcerpc_pipe *spoolss_pipe;
114 : struct spoolss_SetPrinterInfo2 info2;
115 : struct torture_driver_context driver;
116 : bool ex;
117 : bool wellknown;
118 : bool added_driver;
119 : bool have_driver;
120 : struct spoolss_DeviceMode *devmode;
121 : struct policy_handle handle;
122 : };
123 :
124 : static bool upload_printer_driver(struct torture_context *tctx,
125 : const char *server_name,
126 : struct torture_driver_context *d);
127 : static bool remove_printer_driver(struct torture_context *tctx,
128 : const char *server_name,
129 : struct torture_driver_context *d);
130 : static bool fillup_printserver_info(struct torture_context *tctx,
131 : struct dcerpc_pipe *p,
132 : struct torture_driver_context *d);
133 : static bool test_AddPrinterDriver_args_level_3(struct torture_context *tctx,
134 : struct dcerpc_binding_handle *b,
135 : const char *server_name,
136 : struct spoolss_AddDriverInfo8 *r,
137 : uint32_t flags,
138 : bool ex,
139 : const char *remote_driver_dir);
140 :
141 : #define COMPARE_STRING(tctx, c,r,e) \
142 : torture_assert_str_equal(tctx, c.e, r.e, "invalid value")
143 :
144 : /* not every compiler supports __typeof__() */
145 : #if (__GNUC__ >= 3)
146 : #define _CHECK_FIELD_SIZE(c,r,e,type) do {\
147 : if (sizeof(__typeof__(c.e)) != sizeof(type)) { \
148 : torture_fail(tctx, #c "." #e "field is not " #type "\n"); \
149 : }\
150 : if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
151 : torture_fail(tctx, #r "." #e "field is not " #type "\n"); \
152 : }\
153 : } while(0)
154 : #else
155 : #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
156 : #endif
157 :
158 : #define COMPARE_UINT32(tctx, c, r, e) do {\
159 : _CHECK_FIELD_SIZE(c, r, e, uint32_t); \
160 : torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
161 : } while(0)
162 :
163 : #define COMPARE_UINT64(tctx, c, r, e) do {\
164 : _CHECK_FIELD_SIZE(c, r, e, uint64_t); \
165 : torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
166 : } while(0)
167 :
168 :
169 : #define COMPARE_NTTIME(tctx, c, r, e) do {\
170 : _CHECK_FIELD_SIZE(c, r, e, NTTIME); \
171 : torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
172 : } while(0)
173 :
174 : #define COMPARE_STRING_ARRAY(tctx, c,r,e) do {\
175 : int __i; \
176 : if (!c.e && !r.e) { \
177 : break; \
178 : } \
179 : if (c.e && !r.e) { \
180 : torture_fail(tctx, #r "." #e " field is NULL and " #c "." #e " is not\n"); \
181 : } \
182 : if (!c.e && r.e) { \
183 : torture_fail(tctx, #c "." #e " field is NULL and " #r "." #e " is not\n"); \
184 : } \
185 : for (__i=0;c.e[__i] != NULL; __i++) { \
186 : torture_assert_str_equal(tctx, c.e[__i], r.e[__i], "invalid value"); \
187 : } \
188 : } while(0)
189 :
190 : #define CHECK_ALIGN(size, n) do {\
191 : if (size % n) {\
192 : torture_warning(tctx, "%d is *NOT* %d byte aligned, should be %d",\
193 : size, n, size + n - (size % n));\
194 : }\
195 : } while(0)
196 :
197 : #define DO_ROUND(size, n) (((size)+((n)-1)) & ~((n)-1))
198 :
199 : #define CHECK_NEEDED_SIZE_ENUM_LEVEL(fn, info, level, count, needed, align) do { \
200 : if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
201 : uint32_t size = ndr_size_##fn##_info(tctx, level, count, info);\
202 : uint32_t round_size = DO_ROUND(size, align);\
203 : if (round_size != needed) {\
204 : torture_warning(tctx, __location__": "#fn" level %d (count: %d) got unexpected needed size: %d, we calculated: %d", level, count, needed, round_size);\
205 : CHECK_ALIGN(size, align);\
206 : }\
207 : }\
208 : } while(0)
209 :
210 : #define CHECK_NEEDED_SIZE_ENUM(fn, info, count, needed, align) do { \
211 : if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
212 : uint32_t size = ndr_size_##fn##_info(tctx, count, info);\
213 : uint32_t round_size = DO_ROUND(size, align);\
214 : if (round_size != needed) {\
215 : torture_warning(tctx, __location__": "#fn" (count: %d) got unexpected needed size: %d, we calculated: %d", count, needed, round_size);\
216 : CHECK_ALIGN(size, align);\
217 : }\
218 : }\
219 : } while(0)
220 :
221 : #define CHECK_NEEDED_SIZE_LEVEL(fn, info, level, needed, align) do { \
222 : if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
223 : uint32_t size = ndr_size_##fn(info, level, 0);\
224 : uint32_t round_size = DO_ROUND(size, align);\
225 : if (round_size != needed) {\
226 : torture_warning(tctx, __location__": "#fn" level %d got unexpected needed size: %d, we calculated: %d", level, needed, round_size);\
227 : CHECK_ALIGN(size, align);\
228 : }\
229 : }\
230 : } while(0)
231 :
232 60 : static bool PrinterInfo_to_SetPrinterInfo(struct torture_context *tctx,
233 : const union spoolss_PrinterInfo *i,
234 : uint32_t level,
235 : union spoolss_SetPrinterInfo *s)
236 : {
237 60 : switch (level) {
238 0 : case 0:
239 0 : s->info0 = talloc(tctx, struct spoolss_SetPrinterInfo0);
240 0 : break;
241 60 : case 2:
242 60 : s->info2 = talloc(tctx, struct spoolss_SetPrinterInfo2);
243 60 : s->info2->servername = i->info2.servername;
244 60 : s->info2->printername = i->info2.printername;
245 60 : s->info2->sharename = i->info2.sharename;
246 60 : s->info2->portname = i->info2.portname;
247 60 : s->info2->drivername = i->info2.drivername;
248 60 : s->info2->comment = i->info2.comment;
249 60 : s->info2->location = i->info2.location;
250 60 : s->info2->devmode_ptr = 0;
251 60 : s->info2->sepfile = i->info2.sepfile;
252 60 : s->info2->printprocessor = i->info2.printprocessor;
253 60 : s->info2->datatype = i->info2.datatype;
254 60 : s->info2->parameters = i->info2.parameters;
255 60 : s->info2->secdesc_ptr = 0;
256 60 : s->info2->attributes = i->info2.attributes;
257 60 : s->info2->priority = i->info2.priority;
258 60 : s->info2->defaultpriority = i->info2.defaultpriority;
259 60 : s->info2->starttime = i->info2.starttime;
260 60 : s->info2->untiltime = i->info2.untiltime;
261 60 : s->info2->status = i->info2.status;
262 60 : s->info2->cjobs = i->info2.cjobs;
263 60 : s->info2->averageppm = i->info2.averageppm;
264 60 : break;
265 0 : case 3:
266 : case 4:
267 : case 5:
268 : case 6:
269 : case 7:
270 : case 8:
271 : case 9:
272 : default:
273 0 : return false;
274 : }
275 :
276 60 : return true;
277 : }
278 :
279 76 : static bool test_OpenPrinter_server(struct torture_context *tctx,
280 : struct dcerpc_pipe *p,
281 : struct policy_handle *server_handle)
282 : {
283 0 : NTSTATUS status;
284 0 : struct spoolss_OpenPrinter op;
285 76 : struct dcerpc_binding_handle *b = p->binding_handle;
286 :
287 76 : op.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
288 76 : op.in.datatype = NULL;
289 76 : op.in.devmode_ctr.devmode= NULL;
290 76 : op.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
291 76 : op.out.handle = server_handle;
292 :
293 76 : torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
294 :
295 76 : status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &op);
296 76 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed");
297 76 : torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed");
298 :
299 76 : return true;
300 : }
301 :
302 4 : static bool test_EnumPorts(struct torture_context *tctx,
303 : void *private_data)
304 : {
305 0 : struct test_spoolss_context *ctx =
306 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
307 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
308 4 : struct dcerpc_binding_handle *b = p->binding_handle;
309 0 : NTSTATUS status;
310 0 : struct spoolss_EnumPorts r;
311 4 : uint16_t levels[] = { 1, 2 };
312 0 : int i, j;
313 :
314 12 : for (i=0;i<ARRAY_SIZE(levels);i++) {
315 8 : int level = levels[i];
316 0 : DATA_BLOB blob;
317 0 : uint32_t needed;
318 0 : uint32_t count;
319 0 : union spoolss_PortInfo *info;
320 :
321 8 : r.in.servername = "";
322 8 : r.in.level = level;
323 8 : r.in.buffer = NULL;
324 8 : r.in.offered = 0;
325 8 : r.out.needed = &needed;
326 8 : r.out.count = &count;
327 8 : r.out.info = &info;
328 :
329 8 : torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level);
330 :
331 8 : status = dcerpc_spoolss_EnumPorts_r(b, ctx, &r);
332 8 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
333 8 : if (W_ERROR_IS_OK(r.out.result)) {
334 : /* TODO: do some more checks here */
335 0 : continue;
336 : }
337 8 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
338 : "EnumPorts unexpected return code");
339 :
340 8 : blob = data_blob_talloc_zero(ctx, needed);
341 8 : r.in.buffer = &blob;
342 8 : r.in.offered = needed;
343 :
344 8 : status = dcerpc_spoolss_EnumPorts_r(b, ctx, &r);
345 8 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
346 :
347 8 : torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
348 :
349 8 : torture_assert(tctx, info, "EnumPorts returned no info");
350 :
351 8 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, r.in.level, count, needed, 4);
352 :
353 8 : ctx->port_count[level] = count;
354 8 : ctx->ports[level] = info;
355 : }
356 :
357 8 : for (i=1;i<ARRAY_SIZE(levels);i++) {
358 4 : int level = levels[i];
359 4 : int old_level = levels[i-1];
360 4 : torture_assert_int_equal(tctx, ctx->port_count[level], ctx->port_count[old_level],
361 : "EnumPorts invalid value");
362 : }
363 : /* if the array sizes are not the same we would maybe segfault in the following code */
364 :
365 12 : for (i=0;i<ARRAY_SIZE(levels);i++) {
366 8 : int level = levels[i];
367 16 : for (j=0;j<ctx->port_count[level];j++) {
368 8 : union spoolss_PortInfo *cur = &ctx->ports[level][j];
369 8 : union spoolss_PortInfo *ref = &ctx->ports[2][j];
370 8 : switch (level) {
371 4 : case 1:
372 4 : COMPARE_STRING(tctx, cur->info1, ref->info2, port_name);
373 4 : break;
374 4 : case 2:
375 : /* level 2 is our reference, and it makes no sense to compare it to itself */
376 4 : break;
377 : }
378 : }
379 : }
380 :
381 4 : return true;
382 : }
383 :
384 4 : static bool test_GetPrintProcessorDirectory(struct torture_context *tctx,
385 : void *private_data)
386 : {
387 0 : struct test_spoolss_context *ctx =
388 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
389 :
390 0 : NTSTATUS status;
391 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
392 4 : struct dcerpc_binding_handle *b = p->binding_handle;
393 0 : struct spoolss_GetPrintProcessorDirectory r;
394 0 : struct {
395 : uint16_t level;
396 : const char *server;
397 12 : } levels[] = {{
398 : .level = 1,
399 : .server = NULL
400 : },{
401 : .level = 1,
402 : .server = ""
403 : },{
404 : .level = 78,
405 : .server = ""
406 : },{
407 : .level = 1,
408 4 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
409 : },{
410 : .level = 1024,
411 4 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
412 : }
413 : };
414 0 : int i;
415 0 : uint32_t needed;
416 :
417 24 : for (i=0;i<ARRAY_SIZE(levels);i++) {
418 20 : int level = levels[i].level;
419 0 : DATA_BLOB blob;
420 :
421 20 : r.in.server = levels[i].server;
422 20 : r.in.environment = ctx->environment;
423 20 : r.in.level = level;
424 20 : r.in.buffer = NULL;
425 20 : r.in.offered = 0;
426 20 : r.out.needed = &needed;
427 :
428 20 : torture_comment(tctx, "Testing GetPrintProcessorDirectory level %u\n", r.in.level);
429 :
430 20 : status = dcerpc_spoolss_GetPrintProcessorDirectory_r(b, tctx, &r);
431 20 : torture_assert_ntstatus_ok(tctx, status,
432 : "dcerpc_spoolss_GetPrintProcessorDirectory failed");
433 20 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
434 : "GetPrintProcessorDirectory unexpected return code");
435 :
436 20 : blob = data_blob_talloc_zero(tctx, needed);
437 20 : r.in.buffer = &blob;
438 20 : r.in.offered = needed;
439 :
440 20 : status = dcerpc_spoolss_GetPrintProcessorDirectory_r(b, tctx, &r);
441 20 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
442 :
443 20 : torture_assert_werr_ok(tctx, r.out.result, "GetPrintProcessorDirectory failed");
444 :
445 20 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrintProcessorDirectoryInfo, r.out.info, r.in.level, needed, 2);
446 : }
447 :
448 4 : return true;
449 : }
450 :
451 :
452 4 : static bool test_GetPrinterDriverDirectory(struct torture_context *tctx,
453 : void *private_data)
454 : {
455 0 : struct test_spoolss_context *ctx =
456 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
457 :
458 0 : NTSTATUS status;
459 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
460 4 : struct dcerpc_binding_handle *b = p->binding_handle;
461 0 : struct spoolss_GetPrinterDriverDirectory r;
462 0 : struct {
463 : uint16_t level;
464 : const char *server;
465 12 : } levels[] = {{
466 : .level = 1,
467 : .server = NULL
468 : },{
469 : .level = 1,
470 : .server = ""
471 : },{
472 : .level = 78,
473 : .server = ""
474 : },{
475 : .level = 1,
476 4 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
477 : },{
478 : .level = 1024,
479 4 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
480 : }
481 : };
482 0 : int i;
483 0 : uint32_t needed;
484 :
485 24 : for (i=0;i<ARRAY_SIZE(levels);i++) {
486 20 : int level = levels[i].level;
487 0 : DATA_BLOB blob;
488 :
489 20 : r.in.server = levels[i].server;
490 20 : r.in.environment = ctx->environment;
491 20 : r.in.level = level;
492 20 : r.in.buffer = NULL;
493 20 : r.in.offered = 0;
494 20 : r.out.needed = &needed;
495 :
496 20 : torture_comment(tctx, "Testing GetPrinterDriverDirectory level %u\n", r.in.level);
497 :
498 20 : status = dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r);
499 20 : torture_assert_ntstatus_ok(tctx, status,
500 : "dcerpc_spoolss_GetPrinterDriverDirectory failed");
501 20 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
502 : "GetPrinterDriverDirectory unexpected return code");
503 :
504 20 : blob = data_blob_talloc_zero(tctx, needed);
505 20 : r.in.buffer = &blob;
506 20 : r.in.offered = needed;
507 :
508 20 : status = dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r);
509 20 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
510 :
511 20 : torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDriverDirectory failed");
512 :
513 20 : CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverDirectoryInfo, r.out.info, r.in.level, needed, 2);
514 : }
515 :
516 4 : return true;
517 : }
518 :
519 108 : static bool test_EnumPrinterDrivers_buffers(struct torture_context *tctx,
520 : struct dcerpc_binding_handle *b,
521 : const char *server_name,
522 : const char *environment,
523 : uint32_t level,
524 : uint32_t offered,
525 : uint32_t *count_p,
526 : union spoolss_DriverInfo **info_p)
527 : {
528 0 : struct spoolss_EnumPrinterDrivers r;
529 0 : uint32_t needed;
530 0 : uint32_t count;
531 0 : union spoolss_DriverInfo *info;
532 0 : DATA_BLOB buffer;
533 :
534 108 : if (offered > 0) {
535 24 : buffer = data_blob_talloc_zero(tctx, offered);
536 : }
537 :
538 108 : r.in.server = server_name;
539 108 : r.in.environment = environment;
540 108 : r.in.level = level;
541 108 : r.in.buffer = offered ? &buffer : NULL;
542 108 : r.in.offered = offered;
543 108 : r.out.needed = &needed;
544 108 : r.out.count = &count;
545 108 : r.out.info = &info;
546 :
547 108 : torture_comment(tctx, "Testing EnumPrinterDrivers(%s) level %u, offered: %u\n",
548 : r.in.environment, r.in.level, r.in.offered);
549 :
550 108 : torture_assert_ntstatus_ok(tctx,
551 : dcerpc_spoolss_EnumPrinterDrivers_r(b, tctx, &r),
552 : "EnumPrinterDrivers failed");
553 108 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
554 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
555 0 : r.in.buffer = &blob;
556 0 : r.in.offered = needed;
557 :
558 0 : torture_assert_ntstatus_ok(tctx,
559 : dcerpc_spoolss_EnumPrinterDrivers_r(b, tctx, &r),
560 : "EnumPrinterDrivers failed");
561 : }
562 :
563 108 : torture_assert_werr_ok(tctx, r.out.result,
564 : "EnumPrinterDrivers failed");
565 :
566 108 : if (count_p) {
567 76 : *count_p = count;
568 : }
569 108 : if (info_p) {
570 76 : *info_p = info;
571 : }
572 :
573 108 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers, info, r.in.level, count, needed, 4);
574 :
575 108 : return true;
576 :
577 : }
578 :
579 :
580 76 : static bool test_EnumPrinterDrivers_args(struct torture_context *tctx,
581 : struct dcerpc_binding_handle *b,
582 : const char *server_name,
583 : const char *environment,
584 : uint32_t level,
585 : uint32_t *count_p,
586 : union spoolss_DriverInfo **info_p)
587 : {
588 76 : return test_EnumPrinterDrivers_buffers(tctx, b, server_name,
589 : environment, level, 0,
590 : count_p, info_p);
591 : }
592 :
593 16 : static bool test_EnumPrinterDrivers_findone(struct torture_context *tctx,
594 : struct dcerpc_binding_handle *b,
595 : const char *server_name,
596 : const char *environment,
597 : uint32_t level,
598 : const char *driver_name,
599 : union spoolss_DriverInfo *info_p)
600 : {
601 0 : uint32_t count;
602 0 : union spoolss_DriverInfo *info;
603 0 : int i;
604 16 : const char *environment_ret = NULL;
605 :
606 16 : torture_assert(tctx,
607 : test_EnumPrinterDrivers_args(tctx, b, server_name, environment, level, &count, &info),
608 : "failed to enumerate printer drivers");
609 :
610 16 : for (i=0; i < count; i++) {
611 0 : const char *driver_name_ret = "";
612 0 : switch (level) {
613 0 : case 1:
614 0 : driver_name_ret = info[i].info1.driver_name;
615 0 : break;
616 0 : case 2:
617 0 : driver_name_ret = info[i].info2.driver_name;
618 0 : environment_ret = info[i].info2.architecture;
619 0 : break;
620 0 : case 3:
621 0 : driver_name_ret = info[i].info3.driver_name;
622 0 : environment_ret = info[i].info3.architecture;
623 0 : break;
624 0 : case 4:
625 0 : driver_name_ret = info[i].info4.driver_name;
626 0 : environment_ret = info[i].info4.architecture;
627 0 : break;
628 0 : case 5:
629 0 : driver_name_ret = info[i].info5.driver_name;
630 0 : environment_ret = info[i].info5.architecture;
631 0 : break;
632 0 : case 6:
633 0 : driver_name_ret = info[i].info6.driver_name;
634 0 : environment_ret = info[i].info6.architecture;
635 0 : break;
636 0 : case 7:
637 0 : driver_name_ret = info[i].info7.driver_name;
638 0 : break;
639 0 : case 8:
640 0 : driver_name_ret = info[i].info8.driver_name;
641 0 : environment_ret = info[i].info8.architecture;
642 0 : break;
643 0 : default:
644 0 : break;
645 : }
646 0 : if (environment_ret) {
647 0 : torture_assert_str_equal(tctx, environment, environment_ret, "architecture mismatch");
648 : }
649 0 : if (strequal(driver_name, driver_name_ret)) {
650 0 : if (info_p) {
651 0 : *info_p = info[i];
652 : }
653 0 : return true;
654 : }
655 : }
656 :
657 16 : return false;
658 : }
659 :
660 4 : static bool test_EnumPrinterDrivers(struct torture_context *tctx,
661 : void *private_data)
662 : {
663 0 : struct test_spoolss_context *ctx =
664 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
665 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
666 4 : struct dcerpc_binding_handle *b = p->binding_handle;
667 4 : uint16_t levels[] = { 1, 2, 3, 4, 5, 6, 8 };
668 4 : uint16_t buffer_sizes[] = { 0, 1024, 6040, 0xffff };
669 0 : int i, j, a;
670 :
671 : /* FIXME: gd, come back and fix "" as server, and handle
672 : * priority of returned error codes in torture test and samba 3
673 : * server */
674 4 : const char *server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
675 0 : const char *environments[2];
676 :
677 4 : environments[0] = SPOOLSS_ARCHITECTURE_ALL;
678 4 : environments[1] = ctx->environment;
679 :
680 12 : for (a=0;a<ARRAY_SIZE(environments);a++) {
681 :
682 40 : for (i=0;i<ARRAY_SIZE(buffer_sizes);i++) {
683 32 : torture_assert(tctx,
684 : test_EnumPrinterDrivers_buffers(tctx, b, server_name,
685 : environments[a], 3,
686 : buffer_sizes[i],
687 : NULL, NULL),
688 : "failed to enumerate drivers");
689 : }
690 :
691 64 : for (i=0;i<ARRAY_SIZE(levels);i++) {
692 56 : int level = levels[i];
693 0 : uint32_t count;
694 0 : union spoolss_DriverInfo *info;
695 :
696 56 : torture_assert(tctx,
697 : test_EnumPrinterDrivers_args(tctx, b, server_name, environments[a], level, &count, &info),
698 : "failed to enumerate drivers");
699 :
700 56 : ctx->driver_count[level] = count;
701 56 : ctx->drivers[level] = info;
702 : }
703 :
704 56 : for (i=1;i<ARRAY_SIZE(levels);i++) {
705 48 : int level = levels[i];
706 48 : int old_level = levels[i-1];
707 :
708 48 : torture_assert_int_equal(tctx, ctx->driver_count[level], ctx->driver_count[old_level],
709 : "EnumPrinterDrivers invalid value");
710 : }
711 :
712 64 : for (i=0;i<ARRAY_SIZE(levels);i++) {
713 56 : int level = levels[i];
714 :
715 56 : for (j=0;j<ctx->driver_count[level - 1];j++) {
716 0 : union spoolss_DriverInfo *cur = &ctx->drivers[level - 1][j];
717 0 : union spoolss_DriverInfo *ref = &ctx->drivers[8][j];
718 :
719 0 : switch (level) {
720 0 : case 1:
721 0 : COMPARE_STRING(tctx, cur->info1, ref->info8, driver_name);
722 0 : break;
723 0 : case 2:
724 0 : COMPARE_UINT32(tctx, cur->info2, ref->info8, version);
725 0 : COMPARE_STRING(tctx, cur->info2, ref->info8, driver_name);
726 0 : COMPARE_STRING(tctx, cur->info2, ref->info8, architecture);
727 0 : COMPARE_STRING(tctx, cur->info2, ref->info8, driver_path);
728 0 : COMPARE_STRING(tctx, cur->info2, ref->info8, data_file);
729 0 : COMPARE_STRING(tctx, cur->info2, ref->info8, config_file);
730 0 : break;
731 0 : case 3:
732 0 : COMPARE_UINT32(tctx, cur->info3, ref->info8, version);
733 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, driver_name);
734 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, architecture);
735 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, driver_path);
736 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, data_file);
737 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, config_file);
738 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, help_file);
739 0 : COMPARE_STRING_ARRAY(tctx, cur->info3, ref->info8, dependent_files);
740 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, monitor_name);
741 0 : COMPARE_STRING(tctx, cur->info3, ref->info8, default_datatype);
742 0 : break;
743 0 : case 4:
744 0 : COMPARE_UINT32(tctx, cur->info4, ref->info8, version);
745 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, driver_name);
746 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, architecture);
747 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, driver_path);
748 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, data_file);
749 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, config_file);
750 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, help_file);
751 0 : COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info8, dependent_files);
752 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, monitor_name);
753 0 : COMPARE_STRING(tctx, cur->info4, ref->info8, default_datatype);
754 0 : COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info8, previous_names);
755 0 : break;
756 0 : case 5:
757 0 : COMPARE_UINT32(tctx, cur->info5, ref->info8, version);
758 0 : COMPARE_STRING(tctx, cur->info5, ref->info8, driver_name);
759 0 : COMPARE_STRING(tctx, cur->info5, ref->info8, architecture);
760 0 : COMPARE_STRING(tctx, cur->info5, ref->info8, driver_path);
761 0 : COMPARE_STRING(tctx, cur->info5, ref->info8, data_file);
762 0 : COMPARE_STRING(tctx, cur->info5, ref->info8, config_file);
763 : /*COMPARE_UINT32(tctx, cur->info5, ref->info8, driver_attributes);*/
764 : /*COMPARE_UINT32(tctx, cur->info5, ref->info8, config_version);*/
765 : /*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info8, driver_version); */
766 0 : break;
767 0 : case 6:
768 0 : COMPARE_UINT32(tctx, cur->info6, ref->info8, version);
769 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, driver_name);
770 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, architecture);
771 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, driver_path);
772 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, data_file);
773 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, config_file);
774 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, help_file);
775 0 : COMPARE_STRING_ARRAY(tctx, cur->info6, ref->info8, dependent_files);
776 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, monitor_name);
777 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, default_datatype);
778 0 : COMPARE_STRING_ARRAY(tctx, cur->info6, ref->info8, previous_names);
779 0 : COMPARE_NTTIME(tctx, cur->info6, ref->info8, driver_date);
780 0 : COMPARE_UINT64(tctx, cur->info6, ref->info8, driver_version);
781 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, manufacturer_name);
782 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, manufacturer_url);
783 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, hardware_id);
784 0 : COMPARE_STRING(tctx, cur->info6, ref->info8, provider);
785 0 : break;
786 0 : case 8:
787 : /* level 8 is our reference, and it makes no sense to compare it to itself */
788 0 : break;
789 : }
790 : }
791 : }
792 : }
793 :
794 4 : return true;
795 : }
796 :
797 4 : static bool test_EnumMonitors(struct torture_context *tctx,
798 : void *private_data)
799 : {
800 0 : struct test_spoolss_context *ctx =
801 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
802 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
803 4 : struct dcerpc_binding_handle *b = p->binding_handle;
804 0 : NTSTATUS status;
805 0 : struct spoolss_EnumMonitors r;
806 4 : uint16_t levels[] = { 1, 2 };
807 0 : int i, j;
808 :
809 12 : for (i=0;i<ARRAY_SIZE(levels);i++) {
810 8 : int level = levels[i];
811 0 : DATA_BLOB blob;
812 0 : uint32_t needed;
813 0 : uint32_t count;
814 0 : union spoolss_MonitorInfo *info;
815 :
816 8 : r.in.servername = "";
817 8 : r.in.level = level;
818 8 : r.in.buffer = NULL;
819 8 : r.in.offered = 0;
820 8 : r.out.needed = &needed;
821 8 : r.out.count = &count;
822 8 : r.out.info = &info;
823 :
824 8 : torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level);
825 :
826 8 : status = dcerpc_spoolss_EnumMonitors_r(b, ctx, &r);
827 8 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
828 8 : if (W_ERROR_IS_OK(r.out.result)) {
829 : /* TODO: do some more checks here */
830 0 : continue;
831 : }
832 8 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
833 : "EnumMonitors failed");
834 :
835 8 : blob = data_blob_talloc_zero(ctx, needed);
836 8 : r.in.buffer = &blob;
837 8 : r.in.offered = needed;
838 :
839 8 : status = dcerpc_spoolss_EnumMonitors_r(b, ctx, &r);
840 8 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
841 :
842 8 : torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
843 :
844 8 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumMonitors, info, r.in.level, count, needed, 4);
845 :
846 8 : ctx->monitor_count[level] = count;
847 8 : ctx->monitors[level] = info;
848 : }
849 :
850 8 : for (i=1;i<ARRAY_SIZE(levels);i++) {
851 4 : int level = levels[i];
852 4 : int old_level = levels[i-1];
853 4 : torture_assert_int_equal(tctx, ctx->monitor_count[level], ctx->monitor_count[old_level],
854 : "EnumMonitors invalid value");
855 : }
856 :
857 12 : for (i=0;i<ARRAY_SIZE(levels);i++) {
858 8 : int level = levels[i];
859 24 : for (j=0;j<ctx->monitor_count[level];j++) {
860 16 : union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
861 16 : union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
862 16 : switch (level) {
863 8 : case 1:
864 8 : COMPARE_STRING(tctx, cur->info1, ref->info2, monitor_name);
865 8 : break;
866 8 : case 2:
867 8 : torture_assert_str_equal(tctx, ref->info2.environment, ctx->environment, "invalid environment");
868 : /* level 2 is our reference, and it makes no sense to compare it to itself */
869 8 : break;
870 : }
871 : }
872 : }
873 :
874 4 : return true;
875 : }
876 :
877 36 : static bool test_EnumPrintProcessors_level(struct torture_context *tctx,
878 : struct dcerpc_binding_handle *b,
879 : const char *environment,
880 : uint32_t level,
881 : uint32_t *count_p,
882 : union spoolss_PrintProcessorInfo **info_p,
883 : WERROR expected_result)
884 : {
885 0 : struct spoolss_EnumPrintProcessors r;
886 0 : DATA_BLOB blob;
887 0 : uint32_t needed;
888 0 : uint32_t count;
889 0 : union spoolss_PrintProcessorInfo *info;
890 :
891 36 : r.in.servername = "";
892 36 : r.in.environment = environment;
893 36 : r.in.level = level;
894 36 : r.in.buffer = NULL;
895 36 : r.in.offered = 0;
896 36 : r.out.needed = &needed;
897 36 : r.out.count = &count;
898 36 : r.out.info = &info;
899 :
900 36 : torture_comment(tctx, "Testing EnumPrintProcessors(%s) level %u\n",
901 : r.in.environment, r.in.level);
902 :
903 36 : torture_assert_ntstatus_ok(tctx,
904 : dcerpc_spoolss_EnumPrintProcessors_r(b, tctx, &r),
905 : "EnumPrintProcessors failed");
906 36 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
907 12 : blob = data_blob_talloc_zero(tctx, needed);
908 12 : r.in.buffer = &blob;
909 12 : r.in.offered = needed;
910 12 : torture_assert_ntstatus_ok(tctx,
911 : dcerpc_spoolss_EnumPrintProcessors_r(b, tctx, &r),
912 : "EnumPrintProcessors failed");
913 : }
914 36 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
915 : "EnumPrintProcessors failed");
916 :
917 36 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessors, info, level, count, needed, 4);
918 :
919 36 : if (count_p) {
920 32 : *count_p = count;
921 : }
922 36 : if (info_p) {
923 32 : *info_p = info;
924 : }
925 :
926 36 : return true;
927 : }
928 :
929 4 : static bool test_EnumPrintProcessors(struct torture_context *tctx,
930 : void *private_data)
931 : {
932 0 : struct test_spoolss_context *ctx =
933 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
934 :
935 4 : uint16_t levels[] = {0, 1, 2, 3, 32, 256 };
936 4 : uint16_t ok[] = {0, 1, 0, 0, 0, 0 };
937 0 : int i;
938 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
939 4 : struct dcerpc_binding_handle *b = p->binding_handle;
940 :
941 4 : torture_assert(tctx,
942 : test_EnumPrintProcessors_level(tctx, b, "phantasy", 1, NULL, NULL, WERR_INVALID_ENVIRONMENT),
943 : "test_EnumPrintProcessors_level failed");
944 :
945 28 : for (i=0;i<ARRAY_SIZE(levels);i++) {
946 0 : union spoolss_PrintProcessorInfo *info;
947 0 : uint32_t count;
948 24 : WERROR expected_result = ok[i] ? WERR_OK : WERR_INVALID_LEVEL;
949 :
950 24 : torture_assert(tctx,
951 : test_EnumPrintProcessors_level(tctx, b, ctx->environment, levels[i], &count, &info, expected_result),
952 : "test_EnumPrintProcessors_level failed");
953 : }
954 :
955 4 : return true;
956 : }
957 :
958 36 : static bool test_EnumPrintProcessorDataTypes_level(struct torture_context *tctx,
959 : struct dcerpc_binding_handle *b,
960 : const char *print_processor_name,
961 : uint32_t level,
962 : uint32_t *count_p,
963 : union spoolss_PrintProcDataTypesInfo **info_p,
964 : WERROR expected_result)
965 : {
966 0 : struct spoolss_EnumPrintProcessorDataTypes r;
967 0 : DATA_BLOB blob;
968 0 : uint32_t needed;
969 0 : uint32_t count;
970 0 : union spoolss_PrintProcDataTypesInfo *info;
971 :
972 36 : r.in.servername = "";
973 36 : r.in.print_processor_name = print_processor_name;
974 36 : r.in.level = level;
975 36 : r.in.buffer = NULL;
976 36 : r.in.offered = 0;
977 36 : r.out.needed = &needed;
978 36 : r.out.count = &count;
979 36 : r.out.info = &info;
980 :
981 36 : torture_comment(tctx, "Testing EnumPrintProcessorDataTypes(%s) level %u\n",
982 : r.in.print_processor_name, r.in.level);
983 :
984 36 : torture_assert_ntstatus_ok(tctx,
985 : dcerpc_spoolss_EnumPrintProcessorDataTypes_r(b, tctx, &r),
986 : "EnumPrintProcessorDataTypes failed");
987 36 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
988 8 : blob = data_blob_talloc_zero(tctx, needed);
989 8 : r.in.buffer = &blob;
990 8 : r.in.offered = needed;
991 8 : torture_assert_ntstatus_ok(tctx,
992 : dcerpc_spoolss_EnumPrintProcessorDataTypes_r(b, tctx, &r),
993 : "EnumPrintProcessorDataTypes failed");
994 : }
995 36 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
996 : "EnumPrintProcessorDataTypes failed");
997 :
998 36 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessorDataTypes, info, level, count, needed, 4);
999 :
1000 36 : if (count_p) {
1001 24 : *count_p = count;
1002 : }
1003 36 : if (info_p) {
1004 24 : *info_p = info;
1005 : }
1006 :
1007 36 : return true;
1008 : }
1009 :
1010 4 : static bool test_EnumPrintProcessorDataTypes(struct torture_context *tctx,
1011 : void *private_data)
1012 : {
1013 0 : struct test_spoolss_context *ctx =
1014 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
1015 :
1016 4 : uint16_t levels[] = {0, 1, 2, 3, 32, 256 };
1017 4 : uint16_t ok[] = {0, 1, 0, 0, 0, 0 };
1018 0 : int i;
1019 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
1020 4 : struct dcerpc_binding_handle *b = p->binding_handle;
1021 :
1022 4 : torture_assert(tctx,
1023 : test_EnumPrintProcessorDataTypes_level(tctx, b, NULL, 1, NULL, NULL, WERR_UNKNOWN_PRINTPROCESSOR),
1024 : "test_EnumPrintProcessorDataTypes_level failed");
1025 :
1026 4 : torture_assert(tctx,
1027 : test_EnumPrintProcessorDataTypes_level(tctx, b, "nonexisting", 1, NULL, NULL, WERR_UNKNOWN_PRINTPROCESSOR),
1028 : "test_EnumPrintProcessorDataTypes_level failed");
1029 :
1030 28 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1031 24 : int level = levels[i];
1032 0 : uint32_t count;
1033 0 : union spoolss_PrintProcDataTypesInfo *info;
1034 24 : WERROR expected_result = ok[i] ? WERR_OK : WERR_INVALID_LEVEL;
1035 :
1036 24 : torture_assert(tctx,
1037 : test_EnumPrintProcessorDataTypes_level(tctx, b, "winprint", level, &count, &info, expected_result),
1038 : "test_EnumPrintProcessorDataTypes_level failed");
1039 : }
1040 :
1041 : {
1042 0 : union spoolss_PrintProcessorInfo *info;
1043 0 : uint32_t count;
1044 :
1045 4 : torture_assert(tctx,
1046 : test_EnumPrintProcessors_level(tctx, b, ctx->environment, 1, &count, &info, WERR_OK),
1047 : "test_EnumPrintProcessors_level failed");
1048 :
1049 8 : for (i=0; i < count; i++) {
1050 4 : torture_assert(tctx,
1051 : test_EnumPrintProcessorDataTypes_level(tctx, b, info[i].info1.print_processor_name, 1, NULL, NULL, WERR_OK),
1052 : "test_EnumPrintProcessorDataTypes_level failed");
1053 : }
1054 : }
1055 :
1056 :
1057 4 : return true;
1058 : }
1059 :
1060 4 : static bool test_EnumPrinters(struct torture_context *tctx,
1061 : void *private_data)
1062 : {
1063 0 : struct test_spoolss_context *ctx =
1064 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
1065 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
1066 4 : struct dcerpc_binding_handle *b = p->binding_handle;
1067 0 : struct spoolss_EnumPrinters r;
1068 0 : NTSTATUS status;
1069 4 : uint16_t levels[] = { 0, 1, 2, 4, 5 };
1070 0 : int i, j;
1071 :
1072 24 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1073 20 : int level = levels[i];
1074 0 : DATA_BLOB blob;
1075 0 : uint32_t needed;
1076 0 : uint32_t count;
1077 0 : union spoolss_PrinterInfo *info;
1078 :
1079 20 : r.in.flags = PRINTER_ENUM_LOCAL;
1080 20 : r.in.server = "";
1081 20 : r.in.level = level;
1082 20 : r.in.buffer = NULL;
1083 20 : r.in.offered = 0;
1084 20 : r.out.needed = &needed;
1085 20 : r.out.count = &count;
1086 20 : r.out.info = &info;
1087 :
1088 20 : torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
1089 :
1090 20 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &r);
1091 20 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
1092 20 : if (W_ERROR_IS_OK(r.out.result)) {
1093 : /* TODO: do some more checks here */
1094 0 : continue;
1095 : }
1096 20 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
1097 : "EnumPrinters unexpected return code");
1098 :
1099 20 : blob = data_blob_talloc_zero(ctx, needed);
1100 20 : r.in.buffer = &blob;
1101 20 : r.in.offered = needed;
1102 :
1103 20 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &r);
1104 20 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
1105 :
1106 20 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
1107 :
1108 20 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
1109 :
1110 20 : ctx->printer_count[level] = count;
1111 20 : ctx->printers[level] = info;
1112 : }
1113 :
1114 20 : for (i=1;i<ARRAY_SIZE(levels);i++) {
1115 16 : int level = levels[i];
1116 16 : int old_level = levels[i-1];
1117 16 : torture_assert_int_equal(tctx, ctx->printer_count[level], ctx->printer_count[old_level],
1118 : "EnumPrinters invalid value");
1119 : }
1120 :
1121 24 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1122 20 : int level = levels[i];
1123 120 : for (j=0;j<ctx->printer_count[level];j++) {
1124 100 : union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
1125 100 : union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
1126 100 : switch (level) {
1127 20 : case 0:
1128 20 : COMPARE_STRING(tctx, cur->info0, ref->info2, printername);
1129 20 : COMPARE_STRING(tctx, cur->info0, ref->info2, servername);
1130 20 : COMPARE_UINT32(tctx, cur->info0, ref->info2, cjobs);
1131 : /*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs);
1132 : COMPARE_UINT32(tctx, cur->info0, ref->info2, total_bytes);
1133 : COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
1134 : COMPARE_UINT32(tctx, cur->info0, ref->info2, global_counter);
1135 : COMPARE_UINT32(tctx, cur->info0, ref->info2, total_pages);
1136 : COMPARE_UINT32(tctx, cur->info0, ref->info2, version);
1137 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown10);
1138 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown11);
1139 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown12);
1140 : COMPARE_UINT32(tctx, cur->info0, ref->info2, session_counter);
1141 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown14);
1142 : COMPARE_UINT32(tctx, cur->info0, ref->info2, printer_errors);
1143 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown16);
1144 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown17);
1145 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown18);
1146 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown19);
1147 : COMPARE_UINT32(tctx, cur->info0, ref->info2, change_id);
1148 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown21);*/
1149 20 : COMPARE_UINT32(tctx, cur->info0, ref->info2, status);
1150 : /*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23);
1151 : COMPARE_UINT32(tctx, cur->info0, ref->info2, c_setprinter);
1152 : COMPARE_UINT16(cur->info0, ref->info2, unknown25);
1153 : COMPARE_UINT16(cur->info0, ref->info2, unknown26);
1154 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown27);
1155 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown28);
1156 : COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown29);*/
1157 20 : break;
1158 20 : case 1:
1159 : /*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/
1160 : /*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/
1161 : /*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/
1162 20 : COMPARE_STRING(tctx, cur->info1, ref->info2, comment);
1163 20 : break;
1164 20 : case 2:
1165 : /* level 2 is our reference, and it makes no sense to compare it to itself */
1166 20 : break;
1167 20 : case 4:
1168 20 : COMPARE_STRING(tctx, cur->info4, ref->info2, printername);
1169 20 : COMPARE_STRING(tctx, cur->info4, ref->info2, servername);
1170 20 : COMPARE_UINT32(tctx, cur->info4, ref->info2, attributes);
1171 20 : break;
1172 20 : case 5:
1173 20 : COMPARE_STRING(tctx, cur->info5, ref->info2, printername);
1174 20 : COMPARE_STRING(tctx, cur->info5, ref->info2, portname);
1175 20 : COMPARE_UINT32(tctx, cur->info5, ref->info2, attributes);
1176 : /*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout);
1177 : COMPARE_UINT32(tctx, cur->info5, ref->info2, transmission_retry_timeout);*/
1178 20 : break;
1179 : }
1180 : }
1181 : }
1182 :
1183 : /* TODO:
1184 : * - verify that the port of a printer was in the list returned by EnumPorts
1185 : */
1186 :
1187 4 : return true;
1188 : }
1189 :
1190 : static bool test_GetPrinterDriver2(struct torture_context *tctx,
1191 : struct dcerpc_binding_handle *b,
1192 : struct policy_handle *handle,
1193 : const char *driver_name,
1194 : const char *environment);
1195 :
1196 956 : bool test_GetPrinter_level_exp(struct torture_context *tctx,
1197 : struct dcerpc_binding_handle *b,
1198 : struct policy_handle *handle,
1199 : uint32_t level,
1200 : WERROR expected_werror,
1201 : union spoolss_PrinterInfo *info)
1202 : {
1203 0 : struct spoolss_GetPrinter r;
1204 0 : uint32_t needed;
1205 :
1206 956 : r.in.handle = handle;
1207 956 : r.in.level = level;
1208 956 : r.in.buffer = NULL;
1209 956 : r.in.offered = 0;
1210 956 : r.out.needed = &needed;
1211 :
1212 956 : torture_comment(tctx, "Testing GetPrinter level %u\n", r.in.level);
1213 :
1214 956 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
1215 : "GetPrinter failed");
1216 :
1217 956 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1218 924 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
1219 924 : r.in.buffer = &blob;
1220 924 : r.in.offered = needed;
1221 :
1222 924 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
1223 : "GetPrinter failed");
1224 : }
1225 :
1226 956 : torture_assert_werr_equal(tctx,
1227 : r.out.result, expected_werror,
1228 : "GetPrinter failed");
1229 :
1230 956 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo, r.out.info, r.in.level, needed, 4);
1231 :
1232 956 : if (info && r.out.info) {
1233 920 : *info = *r.out.info;
1234 : }
1235 :
1236 956 : return true;
1237 : }
1238 :
1239 924 : bool test_GetPrinter_level(struct torture_context *tctx,
1240 : struct dcerpc_binding_handle *b,
1241 : struct policy_handle *handle,
1242 : uint32_t level,
1243 : union spoolss_PrinterInfo *info)
1244 : {
1245 924 : return test_GetPrinter_level_exp(tctx, b, handle, level, WERR_OK, info);
1246 : }
1247 :
1248 40 : static bool test_GetPrinter(struct torture_context *tctx,
1249 : struct dcerpc_binding_handle *b,
1250 : struct policy_handle *handle,
1251 : const char *environment)
1252 : {
1253 40 : uint32_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1254 0 : int i;
1255 :
1256 400 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1257 :
1258 0 : union spoolss_PrinterInfo info;
1259 :
1260 360 : ZERO_STRUCT(info);
1261 :
1262 360 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, levels[i], &info),
1263 : "failed to call GetPrinter");
1264 :
1265 360 : if ((levels[i] == 2) && info.info2.drivername && strlen(info.info2.drivername)) {
1266 0 : torture_assert(tctx,
1267 : test_GetPrinterDriver2(tctx, b, handle, info.info2.drivername, environment),
1268 : "failed to call test_GetPrinterDriver2");
1269 : }
1270 : }
1271 :
1272 40 : return true;
1273 : }
1274 :
1275 208 : static bool test_SetPrinter(struct torture_context *tctx,
1276 : struct dcerpc_binding_handle *b,
1277 : struct policy_handle *handle,
1278 : struct spoolss_SetPrinterInfoCtr *info_ctr,
1279 : struct spoolss_DevmodeContainer *devmode_ctr,
1280 : struct sec_desc_buf *secdesc_ctr,
1281 : enum spoolss_PrinterControl command)
1282 : {
1283 0 : struct spoolss_SetPrinter r;
1284 :
1285 208 : r.in.handle = handle;
1286 208 : r.in.info_ctr = info_ctr;
1287 208 : r.in.devmode_ctr = devmode_ctr;
1288 208 : r.in.secdesc_ctr = secdesc_ctr;
1289 208 : r.in.command = command;
1290 :
1291 208 : torture_comment(tctx, "Testing SetPrinter level %d\n", r.in.info_ctr->level);
1292 :
1293 208 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter_r(b, tctx, &r),
1294 : "failed to call SetPrinter");
1295 208 : torture_assert(tctx, (W_ERROR_EQUAL(r.out.result, WERR_OK)
1296 : || W_ERROR_EQUAL(r.out.result, WERR_IO_PENDING)),
1297 : "SetPrinter failed");
1298 :
1299 200 : return true;
1300 : }
1301 :
1302 0 : static bool test_SetPrinter_errors(struct torture_context *tctx,
1303 : struct dcerpc_binding_handle *b,
1304 : struct policy_handle *handle)
1305 : {
1306 0 : struct spoolss_SetPrinter r;
1307 0 : uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1308 0 : int i;
1309 :
1310 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
1311 0 : struct spoolss_DevmodeContainer devmode_ctr;
1312 0 : struct sec_desc_buf secdesc_ctr;
1313 :
1314 0 : info_ctr.level = 0;
1315 0 : info_ctr.info.info0 = NULL;
1316 :
1317 0 : ZERO_STRUCT(devmode_ctr);
1318 0 : ZERO_STRUCT(secdesc_ctr);
1319 :
1320 0 : r.in.handle = handle;
1321 0 : r.in.info_ctr = &info_ctr;
1322 0 : r.in.devmode_ctr = &devmode_ctr;
1323 0 : r.in.secdesc_ctr = &secdesc_ctr;
1324 0 : r.in.command = 0;
1325 :
1326 0 : torture_comment(tctx, "Testing SetPrinter all zero\n");
1327 :
1328 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter_r(b, tctx, &r),
1329 : "failed to call SetPrinter");
1330 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
1331 : "failed to call SetPrinter");
1332 :
1333 0 : again:
1334 0 : for (i=0; i < ARRAY_SIZE(levels); i++) {
1335 :
1336 0 : struct spoolss_SetPrinterInfo0 info0;
1337 0 : struct spoolss_SetPrinterInfo1 info1;
1338 0 : struct spoolss_SetPrinterInfo2 info2;
1339 0 : struct spoolss_SetPrinterInfo3 info3;
1340 0 : struct spoolss_SetPrinterInfo4 info4;
1341 0 : struct spoolss_SetPrinterInfo5 info5;
1342 0 : struct spoolss_SetPrinterInfo6 info6;
1343 0 : struct spoolss_SetPrinterInfo7 info7;
1344 0 : struct spoolss_SetPrinterInfo8 info8;
1345 0 : struct spoolss_SetPrinterInfo9 info9;
1346 :
1347 :
1348 0 : info_ctr.level = levels[i];
1349 0 : switch (levels[i]) {
1350 0 : case 0:
1351 0 : ZERO_STRUCT(info0);
1352 0 : info_ctr.info.info0 = &info0;
1353 0 : break;
1354 0 : case 1:
1355 0 : ZERO_STRUCT(info1);
1356 0 : info_ctr.info.info1 = &info1;
1357 0 : break;
1358 0 : case 2:
1359 0 : ZERO_STRUCT(info2);
1360 0 : info_ctr.info.info2 = &info2;
1361 0 : break;
1362 0 : case 3:
1363 0 : ZERO_STRUCT(info3);
1364 0 : info_ctr.info.info3 = &info3;
1365 0 : break;
1366 0 : case 4:
1367 0 : ZERO_STRUCT(info4);
1368 0 : info_ctr.info.info4 = &info4;
1369 0 : break;
1370 0 : case 5:
1371 0 : ZERO_STRUCT(info5);
1372 0 : info_ctr.info.info5 = &info5;
1373 0 : break;
1374 0 : case 6:
1375 0 : ZERO_STRUCT(info6);
1376 0 : info_ctr.info.info6 = &info6;
1377 0 : break;
1378 0 : case 7:
1379 0 : ZERO_STRUCT(info7);
1380 0 : info_ctr.info.info7 = &info7;
1381 0 : break;
1382 0 : case 8:
1383 0 : ZERO_STRUCT(info8);
1384 0 : info_ctr.info.info8 = &info8;
1385 0 : break;
1386 0 : case 9:
1387 0 : ZERO_STRUCT(info9);
1388 0 : info_ctr.info.info9 = &info9;
1389 0 : break;
1390 : }
1391 :
1392 0 : torture_comment(tctx, "Testing SetPrinter level %d, command %d\n",
1393 0 : info_ctr.level, r.in.command);
1394 :
1395 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter_r(b, tctx, &r),
1396 : "failed to call SetPrinter");
1397 :
1398 0 : switch (r.in.command) {
1399 0 : case SPOOLSS_PRINTER_CONTROL_UNPAUSE: /* 0 */
1400 : /* is ignored for all levels other then 0 */
1401 0 : if (info_ctr.level > 0) {
1402 : /* ignored then */
1403 0 : break;
1404 : }
1405 :
1406 0 : FALL_THROUGH;
1407 : case SPOOLSS_PRINTER_CONTROL_PAUSE: /* 1 */
1408 : case SPOOLSS_PRINTER_CONTROL_RESUME: /* 2 */
1409 : case SPOOLSS_PRINTER_CONTROL_PURGE: /* 3 */
1410 0 : if (info_ctr.level > 0) {
1411 : /* is invalid for all levels other then 0 */
1412 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
1413 : "unexpected error code returned");
1414 0 : continue;
1415 : } else {
1416 0 : torture_assert_werr_ok(tctx, r.out.result,
1417 : "failed to call SetPrinter with non 0 command");
1418 0 : continue;
1419 : }
1420 : break;
1421 :
1422 0 : case SPOOLSS_PRINTER_CONTROL_SET_STATUS: /* 4 */
1423 : /* FIXME: gd needs further investigation */
1424 : default:
1425 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
1426 : "unexpected error code returned");
1427 0 : continue;
1428 : }
1429 :
1430 0 : switch (info_ctr.level) {
1431 0 : case 1:
1432 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL,
1433 : "unexpected error code returned");
1434 0 : break;
1435 0 : case 2:
1436 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_PRINTER_DRIVER,
1437 : "unexpected error code returned");
1438 0 : break;
1439 0 : case 3:
1440 : case 4:
1441 : case 5:
1442 : case 7:
1443 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
1444 : "unexpected error code returned");
1445 0 : break;
1446 0 : case 9:
1447 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1448 : "unexpected error code returned");
1449 0 : break;
1450 0 : default:
1451 0 : torture_assert_werr_ok(tctx, r.out.result,
1452 : "failed to call SetPrinter");
1453 0 : break;
1454 : }
1455 : }
1456 :
1457 0 : if (r.in.command < 5) {
1458 0 : r.in.command++;
1459 0 : goto again;
1460 : }
1461 :
1462 0 : return true;
1463 : }
1464 :
1465 272 : static void clear_info2(struct spoolss_SetPrinterInfoCtr *r)
1466 : {
1467 272 : if ((r->level == 2) && (r->info.info2)) {
1468 0 : r->info.info2->secdesc_ptr = 0;
1469 0 : r->info.info2->devmode_ptr = 0;
1470 : }
1471 272 : }
1472 :
1473 0 : static bool test_PrinterInfo(struct torture_context *tctx,
1474 : struct dcerpc_binding_handle *b,
1475 : struct policy_handle *handle)
1476 : {
1477 0 : NTSTATUS status;
1478 0 : struct spoolss_SetPrinter s;
1479 0 : struct spoolss_GetPrinter q;
1480 0 : struct spoolss_GetPrinter q0;
1481 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
1482 0 : union spoolss_PrinterInfo info;
1483 0 : struct spoolss_DevmodeContainer devmode_ctr;
1484 0 : struct sec_desc_buf secdesc_ctr;
1485 0 : uint32_t needed = 0;
1486 0 : DATA_BLOB blob = data_blob_null;
1487 0 : bool ret = true;
1488 0 : int i;
1489 :
1490 0 : uint32_t status_list[] = {
1491 : /* these do not stick
1492 : PRINTER_STATUS_PAUSED,
1493 : PRINTER_STATUS_ERROR,
1494 : PRINTER_STATUS_PENDING_DELETION, */
1495 : PRINTER_STATUS_PAPER_JAM,
1496 : PRINTER_STATUS_PAPER_OUT,
1497 : PRINTER_STATUS_MANUAL_FEED,
1498 : PRINTER_STATUS_PAPER_PROBLEM,
1499 : PRINTER_STATUS_OFFLINE,
1500 : PRINTER_STATUS_IO_ACTIVE,
1501 : PRINTER_STATUS_BUSY,
1502 : PRINTER_STATUS_PRINTING,
1503 : PRINTER_STATUS_OUTPUT_BIN_FULL,
1504 : PRINTER_STATUS_NOT_AVAILABLE,
1505 : PRINTER_STATUS_WAITING,
1506 : PRINTER_STATUS_PROCESSING,
1507 : PRINTER_STATUS_INITIALIZING,
1508 : PRINTER_STATUS_WARMING_UP,
1509 : PRINTER_STATUS_TONER_LOW,
1510 : PRINTER_STATUS_NO_TONER,
1511 : PRINTER_STATUS_PAGE_PUNT,
1512 : PRINTER_STATUS_USER_INTERVENTION,
1513 : PRINTER_STATUS_OUT_OF_MEMORY,
1514 : PRINTER_STATUS_DOOR_OPEN,
1515 : PRINTER_STATUS_SERVER_UNKNOWN,
1516 : PRINTER_STATUS_POWER_SAVE,
1517 : /* these do not stick
1518 : 0x02000000,
1519 : 0x04000000,
1520 : 0x08000000,
1521 : 0x10000000,
1522 : 0x20000000,
1523 : 0x40000000,
1524 : 0x80000000 */
1525 : };
1526 0 : uint32_t default_attribute = PRINTER_ATTRIBUTE_LOCAL;
1527 0 : uint32_t attribute_list[] = {
1528 : PRINTER_ATTRIBUTE_QUEUED,
1529 : /* fails with WERR_INVALID_DATATYPE:
1530 : PRINTER_ATTRIBUTE_DIRECT, */
1531 : /* does not stick
1532 : PRINTER_ATTRIBUTE_DEFAULT, */
1533 : PRINTER_ATTRIBUTE_SHARED,
1534 : /* does not stick
1535 : PRINTER_ATTRIBUTE_NETWORK, */
1536 : PRINTER_ATTRIBUTE_HIDDEN,
1537 : PRINTER_ATTRIBUTE_LOCAL,
1538 : PRINTER_ATTRIBUTE_ENABLE_DEVQ,
1539 : PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS,
1540 : PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST,
1541 : PRINTER_ATTRIBUTE_WORK_OFFLINE,
1542 : /* does not stick
1543 : PRINTER_ATTRIBUTE_ENABLE_BIDI, */
1544 : /* fails with WERR_INVALID_DATATYPE:
1545 : PRINTER_ATTRIBUTE_RAW_ONLY, */
1546 : /* these do not stick
1547 : PRINTER_ATTRIBUTE_PUBLISHED,
1548 : PRINTER_ATTRIBUTE_FAX,
1549 : PRINTER_ATTRIBUTE_TS,
1550 : 0x00010000,
1551 : 0x00020000,
1552 : 0x00040000,
1553 : 0x00080000,
1554 : 0x00100000,
1555 : 0x00200000,
1556 : 0x00400000,
1557 : 0x00800000,
1558 : 0x01000000,
1559 : 0x02000000,
1560 : 0x04000000,
1561 : 0x08000000,
1562 : 0x10000000,
1563 : 0x20000000,
1564 : 0x40000000,
1565 : 0x80000000 */
1566 : };
1567 :
1568 0 : torture_skip(tctx, "Printer Info test is currently broken, skipping");
1569 :
1570 :
1571 : ZERO_STRUCT(devmode_ctr);
1572 : ZERO_STRUCT(secdesc_ctr);
1573 :
1574 : s.in.handle = handle;
1575 : s.in.command = 0;
1576 : s.in.info_ctr = &info_ctr;
1577 : s.in.devmode_ctr = &devmode_ctr;
1578 : s.in.secdesc_ctr = &secdesc_ctr;
1579 :
1580 : q.in.handle = handle;
1581 : q.out.info = &info;
1582 : q0 = q;
1583 :
1584 : #define TESTGETCALL(call, r, needed, blob) \
1585 : r.in.buffer = NULL; \
1586 : r.in.offered = 0;\
1587 : r.out.needed = &needed; \
1588 : status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1589 : if (!NT_STATUS_IS_OK(status)) { \
1590 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1591 : r.in.level, nt_errstr(status), __location__); \
1592 : ret = false; \
1593 : break; \
1594 : }\
1595 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\
1596 : blob = data_blob_talloc_zero(tctx, needed); \
1597 : r.in.buffer = &blob; \
1598 : r.in.offered = needed; \
1599 : }\
1600 : status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1601 : if (!NT_STATUS_IS_OK(status)) { \
1602 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1603 : r.in.level, nt_errstr(status), __location__); \
1604 : ret = false; \
1605 : break; \
1606 : } \
1607 : if (!W_ERROR_IS_OK(r.out.result)) { \
1608 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1609 : r.in.level, win_errstr(r.out.result), __location__); \
1610 : ret = false; \
1611 : break; \
1612 : }
1613 :
1614 :
1615 : #define TESTSETCALL_EXP(call, r, err) \
1616 : clear_info2(&info_ctr);\
1617 : status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1618 : if (!NT_STATUS_IS_OK(status)) { \
1619 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1620 : r.in.info_ctr->level, nt_errstr(status), __location__); \
1621 : ret = false; \
1622 : break; \
1623 : } \
1624 : if (!W_ERROR_IS_OK(err)) { \
1625 : if (!W_ERROR_EQUAL(err, r.out.result)) { \
1626 : torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \
1627 : r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \
1628 : ret = false; \
1629 : } \
1630 : break; \
1631 : } \
1632 : if (!W_ERROR_IS_OK(r.out.result)) { \
1633 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1634 : r.in.info_ctr->level, win_errstr(r.out.result), __location__); \
1635 : ret = false; \
1636 : break; \
1637 : }
1638 :
1639 : #define TESTSETCALL(call, r) \
1640 : TESTSETCALL_EXP(call, r, WERR_OK)
1641 :
1642 : #define STRING_EQUAL(s1, s2, field) \
1643 : if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
1644 : torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1645 : #field, s2, __location__); \
1646 : ret = false; \
1647 : break; \
1648 : }
1649 :
1650 : #define MEM_EQUAL(s1, s2, length, field) \
1651 : if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
1652 : torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1653 : #field, (const char *)s2, __location__); \
1654 : ret = false; \
1655 : break; \
1656 : }
1657 :
1658 : #define INT_EQUAL(i1, i2, field) \
1659 : if (i1 != i2) { \
1660 : torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
1661 : #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
1662 : ret = false; \
1663 : break; \
1664 : }
1665 :
1666 : #define SD_EQUAL(sd1, sd2, field) \
1667 : if (!security_descriptor_equal(sd1, sd2)) { \
1668 : torture_comment(tctx, "Failed to set %s (%s)\n", \
1669 : #field, __location__); \
1670 : ret = false; \
1671 : break; \
1672 : }
1673 :
1674 : #define TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, lvl1, field1, lvl2, field2, value, err) do { \
1675 : void *p; \
1676 : torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1677 : q.in.level = lvl1; \
1678 : TESTGETCALL(GetPrinter, q, needed, blob) \
1679 : info_ctr.level = lvl1; \
1680 : p = (void *)&q.out.info->info ## lvl1; \
1681 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
1682 : info_ctr.info.info ## lvl1->field1 = value;\
1683 : TESTSETCALL_EXP(SetPrinter, s, err) \
1684 : info_ctr.info.info ## lvl1->field1 = ""; \
1685 : TESTGETCALL(GetPrinter, q, needed, blob) \
1686 : info_ctr.info.info ## lvl1->field1 = value; \
1687 : STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \
1688 : q.in.level = lvl2; \
1689 : TESTGETCALL(GetPrinter, q, needed, blob) \
1690 : p = (void *)&q.out.info->info ## lvl2; \
1691 : info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)p; \
1692 : STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \
1693 : } while (0)
1694 :
1695 : #define TEST_PRINTERINFO_STRING(q, s, needed, blob, lvl1, field1, lvl2, field2, value) do { \
1696 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, lvl1, field1, lvl2, field2, value, WERR_OK); \
1697 : } while (0);
1698 :
1699 : #define TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, lvl1, field1, lvl2, field2, value, exp_value) do { \
1700 : void *p; \
1701 : torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1702 : q.in.level = lvl1; \
1703 : TESTGETCALL(GetPrinter, q, needed, blob) \
1704 : info_ctr.level = lvl1; \
1705 : p = (void *)&q.out.info->info ## lvl1; \
1706 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
1707 : info_ctr.info.info ## lvl1->field1 = value; \
1708 : TESTSETCALL(SetPrinter, s) \
1709 : info_ctr.info.info ## lvl1->field1 = 0; \
1710 : TESTGETCALL(GetPrinter, q, needed, blob) \
1711 : p = (void *)&q.out.info->info ## lvl1; \
1712 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
1713 : INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \
1714 : q.in.level = lvl2; \
1715 : TESTGETCALL(GetPrinter, q, needed, blob) \
1716 : p = (void *)&q.out.info->info ## lvl2; \
1717 : info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)p; \
1718 : INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \
1719 : } while (0)
1720 :
1721 : #define TEST_PRINTERINFO_INT(q, s, needed, blob, lvl1, field1, lvl2, field2, value) do { \
1722 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, lvl1, field1, lvl2, field2, value, value); \
1723 : } while (0)
1724 :
1725 : q0.in.level = 0;
1726 : do { TESTGETCALL(GetPrinter, q0, needed, blob) } while (0);
1727 :
1728 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, comment, 1, comment, "xx2-1 comment");
1729 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, comment, 2, comment, "xx2-2 comment");
1730 :
1731 : /* level 0 printername does not stick */
1732 : /* TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, printername, 0, printername, "xx2-0 printer"); */
1733 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, printername, 1, name, "xx2-1 printer");
1734 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, printername, 2, printername, "xx2-2 printer");
1735 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, printername, 4, printername, "xx2-4 printer");
1736 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, printername, 5, printername, "xx2-5 printer");
1737 : /* TEST_PRINTERINFO_STRING(q, s, needed, blob, 4, printername, 0, printername, "xx4-0 printer"); */
1738 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 4, printername, 1, name, "xx4-1 printer");
1739 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 4, printername, 2, printername, "xx4-2 printer");
1740 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 4, printername, 4, printername, "xx4-4 printer");
1741 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 4, printername, 5, printername, "xx4-5 printer");
1742 : /* TEST_PRINTERINFO_STRING(q, s, needed, blob, 5, printername, 0, printername, "xx5-0 printer"); */
1743 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 5, printername, 1, name, "xx5-1 printer");
1744 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 5, printername, 2, printername, "xx5-2 printer");
1745 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 5, printername, 4, printername, "xx5-4 printer");
1746 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 5, printername, 5, printername, "xx5-5 printer");
1747 :
1748 : /* servername can be set but does not stick
1749 : TEST_PRINTERINFO_STRING(q, 2, servername, 0, servername, "xx2-0 servername");
1750 : TEST_PRINTERINFO_STRING(q, 2, servername, 2, servername, "xx2-2 servername");
1751 : TEST_PRINTERINFO_STRING(q, 2, servername, 4, servername, "xx2-4 servername");
1752 : */
1753 :
1754 : /* passing an invalid port will result in WERR_UNKNOWN_PORT */
1755 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, 2, portname, 2, portname, "xx2-2 portname", WERR_UNKNOWN_PORT);
1756 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, 2, portname, 5, portname, "xx2-5 portname", WERR_UNKNOWN_PORT);
1757 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, 5, portname, 2, portname, "xx5-2 portname", WERR_UNKNOWN_PORT);
1758 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, 5, portname, 5, portname, "xx5-5 portname", WERR_UNKNOWN_PORT);
1759 :
1760 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, sharename, 2, sharename, "xx2-2 sharename");
1761 : /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
1762 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, 2, drivername, 2, drivername, "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER);
1763 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, location, 2, location, "xx2-2 location");
1764 : /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
1765 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, 2, sepfile, 2, sepfile, "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE);
1766 : /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
1767 : TEST_PRINTERINFO_STRING_EXP_ERR(q, s, needed, blob, 2, printprocessor, 2, printprocessor, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR);
1768 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, datatype, 2, datatype, "xx2-2 datatype");
1769 : TEST_PRINTERINFO_STRING(q, s, needed, blob, 2, parameters, 2, parameters, "xx2-2 parameters");
1770 :
1771 : for (i=0; i < ARRAY_SIZE(attribute_list); i++) {
1772 : /* TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 2, attributes, 1, flags,
1773 : attribute_list[i],
1774 : (attribute_list[i] | default_attribute)
1775 : ); */
1776 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 2, attributes, 2, attributes,
1777 : attribute_list[i],
1778 : (attribute_list[i] | default_attribute)
1779 : );
1780 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 2, attributes, 4, attributes,
1781 : attribute_list[i],
1782 : (attribute_list[i] | default_attribute)
1783 : );
1784 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 2, attributes, 5, attributes,
1785 : attribute_list[i],
1786 : (attribute_list[i] | default_attribute)
1787 : );
1788 : /* TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 4, attributes, 1, flags,
1789 : attribute_list[i],
1790 : (attribute_list[i] | default_attribute)
1791 : ); */
1792 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 4, attributes, 2, attributes,
1793 : attribute_list[i],
1794 : (attribute_list[i] | default_attribute)
1795 : );
1796 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 4, attributes, 4, attributes,
1797 : attribute_list[i],
1798 : (attribute_list[i] | default_attribute)
1799 : );
1800 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 4, attributes, 5, attributes,
1801 : attribute_list[i],
1802 : (attribute_list[i] | default_attribute)
1803 : );
1804 : /* TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 5, attributes, 1, flags,
1805 : attribute_list[i],
1806 : (attribute_list[i] | default_attribute)
1807 : ); */
1808 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 5, attributes, 2, attributes,
1809 : attribute_list[i],
1810 : (attribute_list[i] | default_attribute)
1811 : );
1812 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 5, attributes, 4, attributes,
1813 : attribute_list[i],
1814 : (attribute_list[i] | default_attribute)
1815 : );
1816 : TEST_PRINTERINFO_INT_EXP(q, s, needed, blob, 5, attributes, 5, attributes,
1817 : attribute_list[i],
1818 : (attribute_list[i] | default_attribute)
1819 : );
1820 : }
1821 :
1822 : for (i=0; i < ARRAY_SIZE(status_list); i++) {
1823 : /* level 2 sets do not stick
1824 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, status, 0, status, status_list[i]);
1825 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, status, 2, status, status_list[i]);
1826 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, status, 6, status, status_list[i]); */
1827 : TEST_PRINTERINFO_INT(q, s, needed, blob, 6, status, 0, status, status_list[i]);
1828 : TEST_PRINTERINFO_INT(q, s, needed, blob, 6, status, 2, status, status_list[i]);
1829 : TEST_PRINTERINFO_INT(q, s, needed, blob, 6, status, 6, status, status_list[i]);
1830 : }
1831 :
1832 : /* priorities need to be between 0 and 99
1833 : passing an invalid priority will result in WERR_INVALID_PRIORITY */
1834 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, priority, 2, priority, 0);
1835 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, priority, 2, priority, 1);
1836 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, priority, 2, priority, 99);
1837 : /* TEST_PRINTERINFO_INT(q, s, needed, blob, 2, priority, 2, priority, 100); */
1838 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, defaultpriority,2, defaultpriority, 0);
1839 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, defaultpriority,2, defaultpriority, 1);
1840 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, defaultpriority,2, defaultpriority, 99);
1841 : /* TEST_PRINTERINFO_INT(q, s, needed, blob, 2, defaultpriority,2, defaultpriority, 100); */
1842 :
1843 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, starttime, 2, starttime, __LINE__);
1844 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, untiltime, 2, untiltime, __LINE__);
1845 :
1846 : /* does not stick
1847 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, cjobs, 2, cjobs, __LINE__);
1848 : TEST_PRINTERINFO_INT(q, s, needed, blob, 2, averageppm, 2, averageppm, __LINE__); */
1849 :
1850 : /* does not stick
1851 : TEST_PRINTERINFO_INT(q, s, needed, blob, 5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__);
1852 : TEST_PRINTERINFO_INT(q, s, needed, blob, 5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */
1853 :
1854 : /* FIXME: gd also test devmode and secdesc behavior */
1855 :
1856 : {
1857 : /* verify composition of level 1 description field */
1858 : const char *description;
1859 : const char *tmp;
1860 :
1861 : q0.in.level = 1;
1862 : do { TESTGETCALL(GetPrinter, q0, needed, blob) } while (0);
1863 :
1864 : description = talloc_strdup(tctx, q0.out.info->info1.description);
1865 :
1866 : q0.in.level = 2;
1867 : do { TESTGETCALL(GetPrinter, q0, needed, blob) } while (0);
1868 :
1869 : tmp = talloc_asprintf(tctx, "%s,%s,%s",
1870 : q0.out.info->info2.printername,
1871 : q0.out.info->info2.drivername,
1872 : q0.out.info->info2.location);
1873 :
1874 : do { STRING_EQUAL(description, tmp, "description")} while (0);
1875 : }
1876 :
1877 : return ret;
1878 : }
1879 :
1880 132 : static bool test_security_descriptor_equal(struct torture_context *tctx,
1881 : const struct security_descriptor *sd1,
1882 : const struct security_descriptor *sd2)
1883 : {
1884 132 : if (sd1 == sd2) {
1885 0 : return true;
1886 : }
1887 :
1888 132 : if (!sd1 || !sd2) {
1889 0 : torture_comment(tctx, "%s\n", __location__);
1890 0 : return false;
1891 : }
1892 :
1893 132 : torture_assert_int_equal(tctx, sd1->revision, sd2->revision, "revision mismatch");
1894 132 : torture_assert_int_equal(tctx, sd1->type, sd2->type, "type mismatch");
1895 :
1896 132 : torture_assert_sid_equal(tctx, sd1->owner_sid, sd2->owner_sid, "owner mismatch");
1897 132 : torture_assert_sid_equal(tctx, sd1->group_sid, sd2->group_sid, "group mismatch");
1898 :
1899 132 : if (!security_acl_equal(sd1->sacl, sd2->sacl)) {
1900 0 : torture_comment(tctx, "%s: sacl mismatch\n", __location__);
1901 0 : NDR_PRINT_DEBUG(security_acl, sd1->sacl);
1902 0 : NDR_PRINT_DEBUG(security_acl, sd2->sacl);
1903 0 : return false;
1904 : }
1905 132 : if (!security_acl_equal(sd1->dacl, sd2->dacl)) {
1906 0 : torture_comment(tctx, "%s: dacl mismatch\n", __location__);
1907 0 : NDR_PRINT_DEBUG(security_acl, sd1->dacl);
1908 0 : NDR_PRINT_DEBUG(security_acl, sd2->dacl);
1909 0 : return false;
1910 : }
1911 :
1912 132 : return true;
1913 : }
1914 :
1915 112 : static bool test_sd_set_level(struct torture_context *tctx,
1916 : struct dcerpc_binding_handle *b,
1917 : struct policy_handle *handle,
1918 : uint32_t level,
1919 : struct security_descriptor *sd)
1920 : {
1921 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
1922 0 : struct spoolss_DevmodeContainer devmode_ctr;
1923 0 : struct sec_desc_buf secdesc_ctr;
1924 0 : union spoolss_SetPrinterInfo sinfo;
1925 0 : union spoolss_PrinterInfo info;
1926 0 : struct spoolss_SetPrinterInfo3 info3;
1927 :
1928 112 : ZERO_STRUCT(devmode_ctr);
1929 112 : ZERO_STRUCT(secdesc_ctr);
1930 :
1931 112 : switch (level) {
1932 28 : case 2: {
1933 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1934 28 : torture_assert(tctx, PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
1935 :
1936 28 : info_ctr.level = 2;
1937 28 : info_ctr.info = sinfo;
1938 :
1939 28 : break;
1940 : }
1941 84 : case 3: {
1942 :
1943 84 : info3.sec_desc_ptr = 0;
1944 :
1945 84 : info_ctr.level = 3;
1946 84 : info_ctr.info.info3 = &info3;
1947 :
1948 84 : break;
1949 : }
1950 0 : default:
1951 0 : return false;
1952 : }
1953 :
1954 112 : secdesc_ctr.sd = sd;
1955 :
1956 112 : torture_assert(tctx,
1957 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0), "");
1958 :
1959 112 : return true;
1960 : }
1961 :
1962 28 : static bool test_PrinterInfo_SDs(struct torture_context *tctx,
1963 : struct dcerpc_binding_handle *b,
1964 : struct policy_handle *handle)
1965 : {
1966 0 : union spoolss_PrinterInfo info;
1967 0 : struct security_descriptor *sd1, *sd2;
1968 0 : int i;
1969 :
1970 : /* just compare level 2 and level 3 */
1971 :
1972 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1973 :
1974 28 : sd1 = info.info2.secdesc;
1975 :
1976 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 3, &info), "");
1977 :
1978 28 : sd2 = info.info3.secdesc;
1979 :
1980 28 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
1981 : "SD level 2 != SD level 3");
1982 :
1983 :
1984 : /* query level 2, set level 2, query level 2 */
1985 :
1986 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1987 :
1988 28 : sd1 = info.info2.secdesc;
1989 :
1990 28 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 2, sd1), "");
1991 :
1992 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1993 :
1994 28 : sd2 = info.info2.secdesc;
1995 28 : if (sd1->type & SEC_DESC_DACL_DEFAULTED) {
1996 0 : torture_comment(tctx, "removing SEC_DESC_DACL_DEFAULTED\n");
1997 0 : sd1->type &= ~SEC_DESC_DACL_DEFAULTED;
1998 : }
1999 :
2000 28 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
2001 : "SD level 2 != SD level 2 after SD has been set via level 2");
2002 :
2003 :
2004 : /* query level 2, set level 3, query level 2 */
2005 :
2006 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2007 :
2008 28 : sd1 = info.info2.secdesc;
2009 :
2010 28 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 3, sd1), "");
2011 :
2012 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2013 :
2014 28 : sd2 = info.info2.secdesc;
2015 :
2016 28 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
2017 : "SD level 2 != SD level 2 after SD has been set via level 3");
2018 :
2019 : /* set modified sd level 3, query level 2 */
2020 :
2021 2632 : for (i=0; i < 93; i++) {
2022 2604 : struct security_ace a = {};
2023 2604 : const char *sid_string = talloc_asprintf(tctx, "S-1-5-32-9999%i", i);
2024 2604 : a.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
2025 2604 : a.flags = 0;
2026 2604 : a.size = 0; /* autogenerated */
2027 2604 : a.access_mask = 0;
2028 2604 : a.trustee = *dom_sid_parse_talloc(tctx, sid_string);
2029 2604 : torture_assert_ntstatus_ok(tctx, security_descriptor_dacl_add(sd1, &a), "");
2030 : }
2031 :
2032 28 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 3, sd1), "");
2033 :
2034 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2035 28 : sd2 = info.info2.secdesc;
2036 :
2037 28 : if (sd1->type & SEC_DESC_DACL_DEFAULTED) {
2038 0 : torture_comment(tctx, "removing SEC_DESC_DACL_DEFAULTED\n");
2039 0 : sd1->type &= ~SEC_DESC_DACL_DEFAULTED;
2040 : }
2041 :
2042 28 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
2043 : "modified SD level 2 != SD level 2 after SD has been set via level 3");
2044 :
2045 :
2046 28 : return true;
2047 : }
2048 :
2049 : /*
2050 : * wrapper call that saves original sd, runs tests, and restores sd
2051 : */
2052 :
2053 28 : static bool test_PrinterInfo_SD(struct torture_context *tctx,
2054 : struct dcerpc_binding_handle *b,
2055 : struct policy_handle *handle)
2056 : {
2057 0 : union spoolss_PrinterInfo info;
2058 0 : struct security_descriptor *sd;
2059 28 : bool ret = true;
2060 :
2061 28 : torture_comment(tctx, "Testing Printer Security Descriptors\n");
2062 :
2063 : /* save original sd */
2064 :
2065 28 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
2066 : "failed to get initial security descriptor");
2067 :
2068 28 : sd = security_descriptor_copy(tctx, info.info2.secdesc);
2069 :
2070 : /* run tests */
2071 :
2072 28 : ret = test_PrinterInfo_SDs(tctx, b, handle);
2073 :
2074 : /* restore original sd */
2075 :
2076 28 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 3, sd),
2077 : "failed to restore initial security descriptor");
2078 :
2079 28 : torture_comment(tctx, "Printer Security Descriptors test %s\n\n",
2080 : ret ? "succeeded" : "failed");
2081 :
2082 :
2083 28 : return ret;
2084 : }
2085 :
2086 32 : static bool test_devmode_set_level(struct torture_context *tctx,
2087 : struct dcerpc_binding_handle *b,
2088 : struct policy_handle *handle,
2089 : uint32_t level,
2090 : struct spoolss_DeviceMode *devmode)
2091 : {
2092 0 : struct spoolss_SetPrinterInfo8 info8;
2093 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
2094 0 : struct spoolss_DevmodeContainer devmode_ctr;
2095 0 : struct sec_desc_buf secdesc_ctr;
2096 0 : union spoolss_SetPrinterInfo sinfo;
2097 :
2098 32 : ZERO_STRUCT(devmode_ctr);
2099 32 : ZERO_STRUCT(secdesc_ctr);
2100 :
2101 32 : switch (level) {
2102 8 : case 2: {
2103 0 : union spoolss_PrinterInfo info;
2104 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2105 8 : torture_assert(tctx, PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
2106 :
2107 8 : info_ctr.level = 2;
2108 8 : info_ctr.info = sinfo;
2109 :
2110 8 : break;
2111 : }
2112 24 : case 8: {
2113 24 : info8.devmode_ptr = 0;
2114 :
2115 24 : info_ctr.level = 8;
2116 24 : info_ctr.info.info8 = &info8;
2117 :
2118 24 : break;
2119 : }
2120 0 : default:
2121 0 : return false;
2122 : }
2123 :
2124 32 : devmode_ctr.devmode = devmode;
2125 :
2126 32 : torture_assert(tctx,
2127 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0), "");
2128 :
2129 32 : return true;
2130 : }
2131 :
2132 :
2133 56 : static bool test_devicemode_equal(struct torture_context *tctx,
2134 : const struct spoolss_DeviceMode *d1,
2135 : const struct spoolss_DeviceMode *d2)
2136 : {
2137 56 : if (d1 == d2) {
2138 0 : return true;
2139 : }
2140 :
2141 56 : if (!d1 || !d2) {
2142 0 : torture_comment(tctx, "%s\n", __location__);
2143 0 : return false;
2144 : }
2145 56 : torture_assert_str_equal(tctx, d1->devicename, d2->devicename, "devicename mismatch");
2146 56 : torture_assert_int_equal(tctx, d1->specversion, d2->specversion, "specversion mismatch");
2147 56 : torture_assert_int_equal(tctx, d1->driverversion, d2->driverversion, "driverversion mismatch");
2148 56 : torture_assert_int_equal(tctx, d1->size, d2->size, "size mismatch");
2149 56 : torture_assert_int_equal(tctx, d1->__driverextra_length, d2->__driverextra_length, "__driverextra_length mismatch");
2150 56 : torture_assert_int_equal(tctx, d1->fields, d2->fields, "fields mismatch");
2151 56 : torture_assert_int_equal(tctx, d1->orientation, d2->orientation, "orientation mismatch");
2152 56 : torture_assert_int_equal(tctx, d1->papersize, d2->papersize, "papersize mismatch");
2153 56 : torture_assert_int_equal(tctx, d1->paperlength, d2->paperlength, "paperlength mismatch");
2154 56 : torture_assert_int_equal(tctx, d1->paperwidth, d2->paperwidth, "paperwidth mismatch");
2155 56 : torture_assert_int_equal(tctx, d1->scale, d2->scale, "scale mismatch");
2156 56 : torture_assert_int_equal(tctx, d1->copies, d2->copies, "copies mismatch");
2157 56 : torture_assert_int_equal(tctx, d1->defaultsource, d2->defaultsource, "defaultsource mismatch");
2158 56 : torture_assert_int_equal(tctx, d1->printquality, d2->printquality, "printquality mismatch");
2159 56 : torture_assert_int_equal(tctx, d1->color, d2->color, "color mismatch");
2160 56 : torture_assert_int_equal(tctx, d1->duplex, d2->duplex, "duplex mismatch");
2161 56 : torture_assert_int_equal(tctx, d1->yresolution, d2->yresolution, "yresolution mismatch");
2162 56 : torture_assert_int_equal(tctx, d1->ttoption, d2->ttoption, "ttoption mismatch");
2163 56 : torture_assert_int_equal(tctx, d1->collate, d2->collate, "collate mismatch");
2164 56 : torture_assert_str_equal(tctx, d1->formname, d2->formname, "formname mismatch");
2165 56 : torture_assert_int_equal(tctx, d1->logpixels, d2->logpixels, "logpixels mismatch");
2166 56 : torture_assert_int_equal(tctx, d1->bitsperpel, d2->bitsperpel, "bitsperpel mismatch");
2167 56 : torture_assert_int_equal(tctx, d1->pelswidth, d2->pelswidth, "pelswidth mismatch");
2168 56 : torture_assert_int_equal(tctx, d1->pelsheight, d2->pelsheight, "pelsheight mismatch");
2169 56 : torture_assert_int_equal(tctx, d1->displayflags, d2->displayflags, "displayflags mismatch");
2170 56 : torture_assert_int_equal(tctx, d1->displayfrequency, d2->displayfrequency, "displayfrequency mismatch");
2171 56 : torture_assert_int_equal(tctx, d1->icmmethod, d2->icmmethod, "icmmethod mismatch");
2172 56 : torture_assert_int_equal(tctx, d1->icmintent, d2->icmintent, "icmintent mismatch");
2173 56 : torture_assert_int_equal(tctx, d1->mediatype, d2->mediatype, "mediatype mismatch");
2174 56 : torture_assert_int_equal(tctx, d1->dithertype, d2->dithertype, "dithertype mismatch");
2175 56 : torture_assert_int_equal(tctx, d1->reserved1, d2->reserved1, "reserved1 mismatch");
2176 56 : torture_assert_int_equal(tctx, d1->reserved2, d2->reserved2, "reserved2 mismatch");
2177 56 : torture_assert_int_equal(tctx, d1->panningwidth, d2->panningwidth, "panningwidth mismatch");
2178 56 : torture_assert_int_equal(tctx, d1->panningheight, d2->panningheight, "panningheight mismatch");
2179 56 : torture_assert_data_blob_equal(tctx, d1->driverextra_data, d2->driverextra_data, "driverextra_data mismatch");
2180 :
2181 56 : return true;
2182 : }
2183 :
2184 8 : static bool test_devicemode_full(struct torture_context *tctx,
2185 : struct dcerpc_binding_handle *b,
2186 : struct policy_handle *handle)
2187 : {
2188 0 : struct spoolss_SetPrinter s;
2189 0 : struct spoolss_GetPrinter q;
2190 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
2191 0 : struct spoolss_SetPrinterInfo8 info8;
2192 0 : union spoolss_PrinterInfo info;
2193 0 : struct spoolss_DevmodeContainer devmode_ctr;
2194 0 : struct sec_desc_buf secdesc_ctr;
2195 8 : uint32_t needed = 0;
2196 8 : DATA_BLOB blob = data_blob_null;
2197 8 : bool ret = true;
2198 0 : NTSTATUS status;
2199 :
2200 : #define TEST_DEVMODE_INT_EXP_RESULT(q, s, needed, blob, lvl1, field1, lvl2, field2, value, exp_value, expected_result) do { \
2201 : torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
2202 : q.in.level = lvl1; \
2203 : TESTGETCALL(GetPrinter, q, needed, blob) \
2204 : info_ctr.level = lvl1; \
2205 : if (lvl1 == 2) {\
2206 : void *p = (void *)&q.out.info->info ## lvl1; \
2207 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
2208 : } else if (lvl1 == 8) {\
2209 : info_ctr.info.info ## lvl1 = &info8; \
2210 : }\
2211 : devmode_ctr.devmode = q.out.info->info ## lvl1.devmode; \
2212 : devmode_ctr.devmode->field1 = value; \
2213 : TESTSETCALL_EXP(SetPrinter, s, expected_result) \
2214 : if (W_ERROR_IS_OK(expected_result)) { \
2215 : TESTGETCALL(GetPrinter, q, needed, blob) \
2216 : INT_EQUAL(q.out.info->info ## lvl1.devmode->field1, exp_value, field1); \
2217 : q.in.level = lvl2; \
2218 : TESTGETCALL(GetPrinter, q, needed, blob) \
2219 : INT_EQUAL(q.out.info->info ## lvl2.devmode->field2, exp_value, field1); \
2220 : }\
2221 : } while (0)
2222 :
2223 : #define TEST_DEVMODE_INT_EXP(q, s, needed, blob, lvl1, field1, lvl2, field2, value, expected_result) do { \
2224 : TEST_DEVMODE_INT_EXP_RESULT(q, s, needed, blob, lvl1, field1, lvl2, field2, value, value, expected_result); \
2225 : } while (0)
2226 :
2227 : #define TEST_DEVMODE_INT(q, s, needed, blob, lvl1, field1, lvl2, field2, value) do { \
2228 : TEST_DEVMODE_INT_EXP_RESULT(q, s, needed, blob, lvl1, field1, lvl2, field2, value, value, WERR_OK); \
2229 : } while (0)
2230 :
2231 8 : ZERO_STRUCT(devmode_ctr);
2232 8 : ZERO_STRUCT(secdesc_ctr);
2233 8 : ZERO_STRUCT(info8);
2234 :
2235 8 : s.in.handle = handle;
2236 8 : s.in.command = 0;
2237 8 : s.in.info_ctr = &info_ctr;
2238 8 : s.in.devmode_ctr = &devmode_ctr;
2239 8 : s.in.secdesc_ctr = &secdesc_ctr;
2240 :
2241 8 : q.in.handle = handle;
2242 8 : q.out.info = &info;
2243 :
2244 : #if 0
2245 : const char *devicename;/* [charset(UTF16)] */
2246 : enum spoolss_DeviceModeSpecVersion specversion;
2247 : uint16_t driverversion;
2248 : uint16_t __driverextra_length;/* [value(r->driverextra_data.length)] */
2249 : uint32_t fields;
2250 : #endif
2251 8 : TEST_DEVMODE_INT_EXP(q, s, needed, blob, 8, size, 8, size, __LINE__, WERR_INVALID_PARAMETER);
2252 8 : TEST_DEVMODE_INT_EXP(q, s, needed, blob, 8, size, 8, size, 0, WERR_INVALID_PARAMETER);
2253 8 : TEST_DEVMODE_INT_EXP(q, s, needed, blob, 8, size, 8, size, 0xffff, WERR_INVALID_PARAMETER);
2254 8 : TEST_DEVMODE_INT_EXP(q, s, needed, blob, 8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0), (devmode_ctr.devmode->__driverextra_length > 0 ) ? WERR_INVALID_PARAMETER : WERR_OK);
2255 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0) - devmode_ctr.devmode->__driverextra_length);
2256 :
2257 8 : devmode_ctr.devmode->driverextra_data = data_blob_string_const("foobar");
2258 8 : torture_assert(tctx,
2259 : test_devmode_set_level(tctx, b, handle, 8, devmode_ctr.devmode),
2260 : "failed to set devmode");
2261 :
2262 8 : TEST_DEVMODE_INT_EXP(q, s, needed, blob, 8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0), (devmode_ctr.devmode->__driverextra_length > 0 ) ? WERR_INVALID_PARAMETER : WERR_OK);
2263 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0) - devmode_ctr.devmode->__driverextra_length);
2264 :
2265 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, orientation, 8, orientation, __LINE__);
2266 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, papersize, 8, papersize, __LINE__);
2267 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, paperlength, 8, paperlength, __LINE__);
2268 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, paperwidth, 8, paperwidth, __LINE__);
2269 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, scale, 8, scale, __LINE__);
2270 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, copies, 8, copies, __LINE__);
2271 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, defaultsource, 8, defaultsource, __LINE__);
2272 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, printquality, 8, printquality, __LINE__);
2273 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, color, 8, color, __LINE__);
2274 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, duplex, 8, duplex, __LINE__);
2275 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, yresolution, 8, yresolution, __LINE__);
2276 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, ttoption, 8, ttoption, __LINE__);
2277 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, collate, 8, collate, __LINE__);
2278 : #if 0
2279 : const char *formname;/* [charset(UTF16)] */
2280 : #endif
2281 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, logpixels, 8, logpixels, __LINE__);
2282 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, bitsperpel, 8, bitsperpel, __LINE__);
2283 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, pelswidth, 8, pelswidth, __LINE__);
2284 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, pelsheight, 8, pelsheight, __LINE__);
2285 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, displayflags, 8, displayflags, __LINE__);
2286 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, displayfrequency, 8, displayfrequency, __LINE__);
2287 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, icmmethod, 8, icmmethod, __LINE__);
2288 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, icmintent, 8, icmintent, __LINE__);
2289 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, mediatype, 8, mediatype, __LINE__);
2290 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, dithertype, 8, dithertype, __LINE__);
2291 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, reserved1, 8, reserved1, __LINE__);
2292 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, reserved2, 8, reserved2, __LINE__);
2293 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, panningwidth, 8, panningwidth, __LINE__);
2294 8 : TEST_DEVMODE_INT(q, s, needed, blob, 8, panningheight, 8, panningheight, __LINE__);
2295 :
2296 8 : return ret;
2297 : }
2298 :
2299 : static bool call_OpenPrinterEx(struct torture_context *tctx,
2300 : struct dcerpc_pipe *p,
2301 : const char *name,
2302 : struct spoolss_DeviceMode *devmode,
2303 : struct policy_handle *handle);
2304 :
2305 8 : static bool test_PrinterInfo_DevModes(struct torture_context *tctx,
2306 : struct dcerpc_pipe *p,
2307 : struct policy_handle *handle,
2308 : const char *name)
2309 : {
2310 0 : union spoolss_PrinterInfo info;
2311 0 : struct spoolss_DeviceMode *devmode;
2312 0 : struct spoolss_DeviceMode *devmode2;
2313 0 : struct policy_handle handle_devmode;
2314 8 : struct dcerpc_binding_handle *b = p->binding_handle;
2315 :
2316 : /* simply compare level8 and level2 devmode */
2317 :
2318 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info), "");
2319 :
2320 8 : devmode = info.info8.devmode;
2321 :
2322 8 : if (devmode && devmode->size == 0) {
2323 0 : torture_fail(tctx,
2324 : "devmode of zero size!");
2325 : }
2326 :
2327 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2328 :
2329 8 : devmode2 = info.info2.devmode;
2330 :
2331 8 : if (devmode2 && devmode2->size == 0) {
2332 0 : torture_fail(tctx,
2333 : "devmode of zero size!");
2334 : }
2335 :
2336 8 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2337 : "DM level 8 != DM level 2");
2338 :
2339 :
2340 : /* set devicemode level 8 and see if it persists */
2341 :
2342 8 : devmode->copies = 93;
2343 8 : devmode->formname = talloc_strdup(tctx, "Legal");
2344 :
2345 8 : torture_assert(tctx, test_devmode_set_level(tctx, b, handle, 8, devmode), "");
2346 :
2347 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info), "");
2348 :
2349 8 : devmode2 = info.info8.devmode;
2350 :
2351 8 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2352 : "modified DM level 8 != DM level 8 after DM has been set via level 8");
2353 :
2354 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2355 :
2356 8 : devmode2 = info.info2.devmode;
2357 :
2358 8 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2359 : "modified DM level 8 != DM level 2");
2360 :
2361 :
2362 : /* set devicemode level 2 and see if it persists */
2363 :
2364 8 : devmode->copies = 39;
2365 8 : devmode->formname = talloc_strdup(tctx, "Executive");
2366 :
2367 8 : torture_assert(tctx, test_devmode_set_level(tctx, b, handle, 2, devmode), "");
2368 :
2369 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info), "");
2370 :
2371 8 : devmode2 = info.info8.devmode;
2372 :
2373 8 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2374 : "modified DM level 8 != DM level 8 after DM has been set via level 2");
2375 :
2376 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2377 :
2378 8 : devmode2 = info.info2.devmode;
2379 :
2380 8 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2381 : "modified DM level 8 != DM level 2");
2382 :
2383 :
2384 : /* check every single bit in public part of devicemode */
2385 :
2386 8 : torture_assert(tctx, test_devicemode_full(tctx, b, handle),
2387 : "failed to set every single devicemode component");
2388 :
2389 :
2390 : /* change formname upon open and see if it persists in getprinter calls */
2391 :
2392 8 : devmode->formname = talloc_strdup(tctx, "A4");
2393 8 : devmode->copies = 42;
2394 :
2395 8 : torture_assert(tctx, call_OpenPrinterEx(tctx, p, name, devmode, &handle_devmode),
2396 : "failed to open printer handle");
2397 :
2398 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, &handle_devmode, 8, &info), "");
2399 :
2400 8 : devmode2 = info.info8.devmode;
2401 :
2402 8 : if (strequal(devmode->devicename, devmode2->devicename)) {
2403 0 : torture_warning(tctx, "devicenames are the same\n");
2404 : } else {
2405 8 : torture_comment(tctx, "devicename passed in for open: %s\n", devmode->devicename);
2406 8 : torture_comment(tctx, "devicename after level 8 get: %s\n", devmode2->devicename);
2407 : }
2408 :
2409 8 : if (strequal(devmode->formname, devmode2->formname)) {
2410 0 : torture_warning(tctx, "formname are the same\n");
2411 : } else {
2412 8 : torture_comment(tctx, "formname passed in for open: %s\n", devmode->formname);
2413 8 : torture_comment(tctx, "formname after level 8 get: %s\n", devmode2->formname);
2414 : }
2415 :
2416 8 : if (devmode->copies == devmode2->copies) {
2417 0 : torture_warning(tctx, "copies are the same\n");
2418 : } else {
2419 8 : torture_comment(tctx, "copies passed in for open: %d\n", devmode->copies);
2420 8 : torture_comment(tctx, "copies after level 8 get: %d\n", devmode2->copies);
2421 : }
2422 :
2423 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, &handle_devmode, 2, &info), "");
2424 :
2425 8 : devmode2 = info.info2.devmode;
2426 :
2427 8 : if (strequal(devmode->devicename, devmode2->devicename)) {
2428 0 : torture_warning(tctx, "devicenames are the same\n");
2429 : } else {
2430 8 : torture_comment(tctx, "devicename passed in for open: %s\n", devmode->devicename);
2431 8 : torture_comment(tctx, "devicename after level 2 get: %s\n", devmode2->devicename);
2432 : }
2433 :
2434 8 : if (strequal(devmode->formname, devmode2->formname)) {
2435 0 : torture_warning(tctx, "formname is the same\n");
2436 : } else {
2437 8 : torture_comment(tctx, "formname passed in for open: %s\n", devmode->formname);
2438 8 : torture_comment(tctx, "formname after level 2 get: %s\n", devmode2->formname);
2439 : }
2440 :
2441 8 : if (devmode->copies == devmode2->copies) {
2442 0 : torture_warning(tctx, "copies are the same\n");
2443 : } else {
2444 8 : torture_comment(tctx, "copies passed in for open: %d\n", devmode->copies);
2445 8 : torture_comment(tctx, "copies after level 2 get: %d\n", devmode2->copies);
2446 : }
2447 :
2448 8 : test_ClosePrinter(tctx, b, &handle_devmode);
2449 :
2450 8 : return true;
2451 : }
2452 :
2453 : /*
2454 : * wrapper call that saves original devmode, runs tests, and restores devmode
2455 : */
2456 :
2457 8 : static bool test_PrinterInfo_DevMode(struct torture_context *tctx,
2458 : struct dcerpc_pipe *p,
2459 : struct policy_handle *handle,
2460 : const char *name,
2461 : struct spoolss_DeviceMode *addprinter_devmode)
2462 : {
2463 0 : union spoolss_PrinterInfo info;
2464 0 : struct spoolss_DeviceMode *devmode;
2465 8 : bool ret = true;
2466 8 : struct dcerpc_binding_handle *b = p->binding_handle;
2467 :
2468 8 : torture_comment(tctx, "Testing Printer Devicemodes\n");
2469 :
2470 : /* save original devmode */
2471 :
2472 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info),
2473 : "failed to get initial global devicemode");
2474 :
2475 8 : devmode = info.info8.devmode;
2476 :
2477 8 : if (devmode && devmode->size == 0) {
2478 0 : torture_fail(tctx,
2479 : "devmode of zero size!");
2480 : }
2481 :
2482 8 : if (addprinter_devmode) {
2483 0 : if (!test_devicemode_equal(tctx, devmode, addprinter_devmode)) {
2484 0 : torture_warning(tctx, "current global DM is != DM provided in addprinter");
2485 : }
2486 : }
2487 :
2488 : /* run tests */
2489 :
2490 8 : ret = test_PrinterInfo_DevModes(tctx, p, handle, name);
2491 :
2492 : /* restore original devmode */
2493 :
2494 8 : torture_assert(tctx, test_devmode_set_level(tctx, b, handle, 8, devmode),
2495 : "failed to restore initial global device mode");
2496 :
2497 8 : torture_comment(tctx, "Printer Devicemodes test %s\n\n",
2498 : ret ? "succeeded" : "failed");
2499 :
2500 :
2501 8 : return ret;
2502 : }
2503 :
2504 574 : bool test_ClosePrinter(struct torture_context *tctx,
2505 : struct dcerpc_binding_handle *b,
2506 : struct policy_handle *handle)
2507 : {
2508 0 : NTSTATUS status;
2509 0 : struct spoolss_ClosePrinter r;
2510 :
2511 574 : r.in.handle = handle;
2512 574 : r.out.handle = handle;
2513 :
2514 574 : torture_comment(tctx, "Testing ClosePrinter\n");
2515 :
2516 574 : status = dcerpc_spoolss_ClosePrinter_r(b, tctx, &r);
2517 574 : torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
2518 574 : torture_assert_werr_ok(tctx, r.out.result, "ClosePrinter failed");
2519 :
2520 574 : return true;
2521 : }
2522 :
2523 2520 : static bool test_GetForm_args(struct torture_context *tctx,
2524 : struct dcerpc_binding_handle *b,
2525 : struct policy_handle *handle,
2526 : const char *form_name,
2527 : uint32_t level,
2528 : union spoolss_FormInfo *info_p)
2529 : {
2530 0 : NTSTATUS status;
2531 0 : struct spoolss_GetForm r;
2532 0 : uint32_t needed;
2533 :
2534 2520 : r.in.handle = handle;
2535 2520 : r.in.form_name = form_name;
2536 2520 : r.in.level = level;
2537 2520 : r.in.buffer = NULL;
2538 2520 : r.in.offered = 0;
2539 2520 : r.out.needed = &needed;
2540 :
2541 2520 : torture_comment(tctx, "Testing GetForm(%s) level %d\n", form_name, r.in.level);
2542 :
2543 2520 : status = dcerpc_spoolss_GetForm_r(b, tctx, &r);
2544 2520 : torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
2545 :
2546 2520 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2547 2520 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
2548 2520 : r.in.buffer = &blob;
2549 2520 : r.in.offered = needed;
2550 2520 : status = dcerpc_spoolss_GetForm_r(b, tctx, &r);
2551 2520 : torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
2552 :
2553 2520 : torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
2554 :
2555 2520 : torture_assert(tctx, r.out.info, "No form info returned");
2556 : }
2557 :
2558 2520 : torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
2559 :
2560 2520 : CHECK_NEEDED_SIZE_LEVEL(spoolss_FormInfo, r.out.info, r.in.level, needed, 4);
2561 :
2562 2520 : if (info_p) {
2563 160 : *info_p = *r.out.info;
2564 : }
2565 :
2566 2520 : return true;
2567 : }
2568 :
2569 2360 : static bool test_GetForm(struct torture_context *tctx,
2570 : struct dcerpc_binding_handle *b,
2571 : struct policy_handle *handle,
2572 : const char *form_name,
2573 : uint32_t level)
2574 : {
2575 2360 : return test_GetForm_args(tctx, b, handle, form_name, level, NULL);
2576 : }
2577 :
2578 288 : static bool test_EnumForms(struct torture_context *tctx,
2579 : struct dcerpc_binding_handle *b,
2580 : struct policy_handle *handle,
2581 : bool print_server,
2582 : uint32_t level,
2583 : uint32_t *count_p,
2584 : union spoolss_FormInfo **info_p)
2585 : {
2586 0 : struct spoolss_EnumForms r;
2587 0 : uint32_t needed;
2588 0 : uint32_t count;
2589 0 : union spoolss_FormInfo *info;
2590 :
2591 288 : r.in.handle = handle;
2592 288 : r.in.level = level;
2593 288 : r.in.buffer = NULL;
2594 288 : r.in.offered = 0;
2595 288 : r.out.needed = &needed;
2596 288 : r.out.count = &count;
2597 288 : r.out.info = &info;
2598 :
2599 288 : torture_comment(tctx, "Testing EnumForms level %d\n", r.in.level);
2600 :
2601 288 : torture_assert_ntstatus_ok(tctx,
2602 : dcerpc_spoolss_EnumForms_r(b, tctx, &r),
2603 : "EnumForms failed");
2604 :
2605 288 : if ((r.in.level == 2) && (W_ERROR_EQUAL(r.out.result, WERR_INVALID_LEVEL))) {
2606 24 : torture_skip(tctx, "EnumForms level 2 not supported");
2607 : }
2608 :
2609 264 : if (print_server && W_ERROR_EQUAL(r.out.result, WERR_INVALID_HANDLE)) {
2610 0 : torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)");
2611 : }
2612 :
2613 264 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2614 264 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
2615 264 : r.in.buffer = &blob;
2616 264 : r.in.offered = needed;
2617 :
2618 264 : torture_assert_ntstatus_ok(tctx,
2619 : dcerpc_spoolss_EnumForms_r(b, tctx, &r),
2620 : "EnumForms failed");
2621 :
2622 264 : torture_assert(tctx, info, "No forms returned");
2623 : }
2624 :
2625 264 : torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
2626 :
2627 264 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumForms, info, r.in.level, count, needed, 4);
2628 :
2629 264 : if (info_p) {
2630 264 : *info_p = info;
2631 : }
2632 264 : if (count_p) {
2633 264 : *count_p = count;
2634 : }
2635 :
2636 264 : return true;
2637 : }
2638 :
2639 24 : static bool test_EnumForms_all(struct torture_context *tctx,
2640 : struct dcerpc_binding_handle *b,
2641 : struct policy_handle *handle,
2642 : bool print_server)
2643 : {
2644 24 : uint32_t levels[] = { 1, 2 };
2645 0 : int i, j;
2646 :
2647 72 : for (i=0; i<ARRAY_SIZE(levels); i++) {
2648 :
2649 48 : uint32_t count = 0;
2650 48 : union spoolss_FormInfo *info = NULL;
2651 :
2652 48 : torture_assert(tctx,
2653 : test_EnumForms(tctx, b, handle, print_server, levels[i], &count, &info),
2654 : "failed to enum forms");
2655 :
2656 2880 : for (j = 0; j < count; j++) {
2657 2832 : if (!print_server) {
2658 2360 : torture_assert(tctx,
2659 : test_GetForm(tctx, b, handle, info[j].info1.form_name, levels[i]),
2660 : "failed to get form");
2661 : }
2662 : }
2663 : }
2664 :
2665 24 : return true;
2666 : }
2667 :
2668 240 : static bool test_EnumForms_find_one(struct torture_context *tctx,
2669 : struct dcerpc_binding_handle *b,
2670 : struct policy_handle *handle,
2671 : bool print_server,
2672 : const char *form_name)
2673 : {
2674 240 : union spoolss_FormInfo *info = NULL;
2675 240 : uint32_t count = 0;
2676 240 : bool found = false;
2677 0 : int i;
2678 :
2679 240 : torture_assert(tctx,
2680 : test_EnumForms(tctx, b, handle, print_server, 1, &count, &info),
2681 : "failed to enumerate forms");
2682 :
2683 11568 : for (i=0; i<count; i++) {
2684 11568 : if (strequal(form_name, info[i].info1.form_name)) {
2685 240 : found = true;
2686 240 : break;
2687 : }
2688 : }
2689 :
2690 240 : return found;
2691 : }
2692 :
2693 288 : static bool test_DeleteForm(struct torture_context *tctx,
2694 : struct dcerpc_binding_handle *b,
2695 : struct policy_handle *handle,
2696 : const char *form_name,
2697 : WERROR expected_result)
2698 : {
2699 0 : struct spoolss_DeleteForm r;
2700 :
2701 288 : r.in.handle = handle;
2702 288 : r.in.form_name = form_name;
2703 :
2704 288 : torture_comment(tctx, "Testing DeleteForm(%s)\n", form_name);
2705 :
2706 288 : torture_assert_ntstatus_ok(tctx,
2707 : dcerpc_spoolss_DeleteForm_r(b, tctx, &r),
2708 : "DeleteForm failed");
2709 288 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
2710 : "DeleteForm gave unexpected result");
2711 288 : if (W_ERROR_IS_OK(r.out.result)) {
2712 96 : torture_assert_ntstatus_ok(tctx,
2713 : dcerpc_spoolss_DeleteForm_r(b, tctx, &r),
2714 : "2nd DeleteForm failed");
2715 96 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_FORM_NAME,
2716 : "2nd DeleteForm failed");
2717 : }
2718 :
2719 288 : return true;
2720 : }
2721 :
2722 288 : static bool test_AddForm(struct torture_context *tctx,
2723 : struct dcerpc_binding_handle *b,
2724 : struct policy_handle *handle,
2725 : uint32_t level,
2726 : union spoolss_AddFormInfo *info,
2727 : WERROR expected_result)
2728 : {
2729 0 : struct spoolss_AddForm r;
2730 0 : struct spoolss_AddFormInfoCtr info_ctr;
2731 :
2732 288 : info_ctr.level = level;
2733 288 : info_ctr.info = *info;
2734 :
2735 288 : if (level != 1) {
2736 0 : torture_skip(tctx, "only level 1 supported");
2737 : }
2738 :
2739 288 : r.in.handle = handle;
2740 288 : r.in.info_ctr = &info_ctr;
2741 :
2742 288 : torture_comment(tctx, "Testing AddForm(%s) level %d, type %d\n",
2743 288 : r.in.info_ctr->info.info1->form_name, level,
2744 288 : r.in.info_ctr->info.info1->flags);
2745 :
2746 288 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_AddForm_r(b, tctx, &r),
2747 : "AddForm failed");
2748 288 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
2749 : "AddForm gave unexpected result");
2750 :
2751 288 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_AddForm_r(b, tctx, &r),
2752 : "2nd AddForm failed");
2753 288 : if (W_ERROR_EQUAL(expected_result, WERR_INVALID_PARAMETER)) {
2754 48 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2755 : "2nd AddForm gave unexpected result");
2756 : } else {
2757 240 : torture_assert_werr_equal(tctx, r.out.result, WERR_FILE_EXISTS,
2758 : "2nd AddForm gave unexpected result");
2759 : }
2760 :
2761 288 : return true;
2762 : }
2763 :
2764 80 : static bool test_SetForm(struct torture_context *tctx,
2765 : struct dcerpc_binding_handle *b,
2766 : struct policy_handle *handle,
2767 : const char *form_name,
2768 : uint32_t level,
2769 : union spoolss_AddFormInfo *info)
2770 : {
2771 0 : struct spoolss_SetForm r;
2772 0 : struct spoolss_AddFormInfoCtr info_ctr;
2773 :
2774 80 : info_ctr.level = level;
2775 80 : info_ctr.info = *info;
2776 :
2777 80 : r.in.handle = handle;
2778 80 : r.in.form_name = form_name;
2779 80 : r.in.info_ctr = &info_ctr;
2780 :
2781 80 : torture_comment(tctx, "Testing SetForm(%s) level %d\n",
2782 : form_name, level);
2783 :
2784 80 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetForm_r(b, tctx, &r),
2785 : "SetForm failed");
2786 :
2787 80 : torture_assert_werr_ok(tctx, r.out.result,
2788 : "SetForm failed");
2789 :
2790 80 : return true;
2791 : }
2792 :
2793 : static bool test_GetForm_winreg(struct torture_context *tctx,
2794 : struct dcerpc_binding_handle *b,
2795 : struct policy_handle *handle,
2796 : const char *key_name,
2797 : const char *form_name,
2798 : enum winreg_Type *w_type,
2799 : uint32_t *w_size,
2800 : uint32_t *w_length,
2801 : uint8_t **w_data);
2802 :
2803 288 : static bool test_Forms_args(struct torture_context *tctx,
2804 : struct dcerpc_binding_handle *b,
2805 : struct policy_handle *handle,
2806 : bool print_server,
2807 : const char *printer_name,
2808 : struct dcerpc_binding_handle *winreg_handle,
2809 : struct policy_handle *hive_handle,
2810 : const char *form_name,
2811 : struct spoolss_AddFormInfo1 *info1,
2812 : WERROR expected_add_result,
2813 : WERROR expected_delete_result)
2814 : {
2815 0 : union spoolss_FormInfo info;
2816 0 : union spoolss_AddFormInfo add_info;
2817 :
2818 0 : enum winreg_Type w_type;
2819 0 : uint32_t w_size;
2820 0 : uint32_t w_length;
2821 0 : uint8_t *w_data;
2822 :
2823 288 : add_info.info1 = info1;
2824 :
2825 288 : torture_assert(tctx,
2826 : test_AddForm(tctx, b, handle, 1, &add_info, expected_add_result),
2827 : "failed to add form");
2828 :
2829 288 : if (winreg_handle && hive_handle && W_ERROR_IS_OK(expected_add_result)) {
2830 :
2831 0 : struct spoolss_FormInfo1 i1;
2832 :
2833 48 : torture_assert(tctx,
2834 : test_GetForm_winreg(tctx, winreg_handle, hive_handle, TOP_LEVEL_CONTROL_FORMS_KEY, form_name, &w_type, &w_size, &w_length, &w_data),
2835 : "failed to get form via winreg");
2836 :
2837 48 : i1.size.width = IVAL(w_data, 0);
2838 48 : i1.size.height = IVAL(w_data, 4);
2839 48 : i1.area.left = IVAL(w_data, 8);
2840 48 : i1.area.top = IVAL(w_data, 12);
2841 48 : i1.area.right = IVAL(w_data, 16);
2842 48 : i1.area.bottom = IVAL(w_data, 20);
2843 : /* skip index here */
2844 48 : i1.flags = IVAL(w_data, 28);
2845 :
2846 48 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");
2847 48 : torture_assert_int_equal(tctx, w_size, 0x20, "unexpected size");
2848 48 : torture_assert_int_equal(tctx, w_length, 0x20, "unexpected length");
2849 48 : torture_assert_int_equal(tctx, i1.size.width, add_info.info1->size.width, "width mismatch");
2850 48 : torture_assert_int_equal(tctx, i1.size.height, add_info.info1->size.height, "height mismatch");
2851 48 : torture_assert_int_equal(tctx, i1.area.left, add_info.info1->area.left, "left mismatch");
2852 48 : torture_assert_int_equal(tctx, i1.area.top, add_info.info1->area.top, "top mismatch");
2853 48 : torture_assert_int_equal(tctx, i1.area.right, add_info.info1->area.right, "right mismatch");
2854 48 : torture_assert_int_equal(tctx, i1.area.bottom, add_info.info1->area.bottom, "bottom mismatch");
2855 48 : torture_assert_int_equal(tctx, i1.flags, add_info.info1->flags, "flags mismatch");
2856 : }
2857 :
2858 288 : if (!print_server && W_ERROR_IS_OK(expected_add_result)) {
2859 80 : torture_assert(tctx,
2860 : test_GetForm_args(tctx, b, handle, form_name, 1, &info),
2861 : "failed to get added form");
2862 :
2863 80 : torture_assert_int_equal(tctx, info.info1.size.width, add_info.info1->size.width, "width mismatch");
2864 80 : torture_assert_int_equal(tctx, info.info1.size.height, add_info.info1->size.height, "height mismatch");
2865 80 : torture_assert_int_equal(tctx, info.info1.area.left, add_info.info1->area.left, "left mismatch");
2866 80 : torture_assert_int_equal(tctx, info.info1.area.top, add_info.info1->area.top, "top mismatch");
2867 80 : torture_assert_int_equal(tctx, info.info1.area.right, add_info.info1->area.right, "right mismatch");
2868 80 : torture_assert_int_equal(tctx, info.info1.area.bottom, add_info.info1->area.bottom, "bottom mismatch");
2869 80 : torture_assert_int_equal(tctx, info.info1.flags, add_info.info1->flags, "flags mismatch");
2870 :
2871 80 : if (winreg_handle && hive_handle) {
2872 :
2873 0 : struct spoolss_FormInfo1 i1;
2874 :
2875 40 : i1.size.width = IVAL(w_data, 0);
2876 40 : i1.size.height = IVAL(w_data, 4);
2877 40 : i1.area.left = IVAL(w_data, 8);
2878 40 : i1.area.top = IVAL(w_data, 12);
2879 40 : i1.area.right = IVAL(w_data, 16);
2880 40 : i1.area.bottom = IVAL(w_data, 20);
2881 : /* skip index here */
2882 40 : i1.flags = IVAL(w_data, 28);
2883 :
2884 40 : torture_assert_int_equal(tctx, i1.size.width, info.info1.size.width, "width mismatch");
2885 40 : torture_assert_int_equal(tctx, i1.size.height, info.info1.size.height, "height mismatch");
2886 40 : torture_assert_int_equal(tctx, i1.area.left, info.info1.area.left, "left mismatch");
2887 40 : torture_assert_int_equal(tctx, i1.area.top, info.info1.area.top, "top mismatch");
2888 40 : torture_assert_int_equal(tctx, i1.area.right, info.info1.area.right, "right mismatch");
2889 40 : torture_assert_int_equal(tctx, i1.area.bottom, info.info1.area.bottom, "bottom mismatch");
2890 40 : torture_assert_int_equal(tctx, i1.flags, info.info1.flags, "flags mismatch");
2891 : }
2892 :
2893 80 : add_info.info1->size.width = 1234;
2894 :
2895 80 : torture_assert(tctx,
2896 : test_SetForm(tctx, b, handle, form_name, 1, &add_info),
2897 : "failed to set form");
2898 80 : torture_assert(tctx,
2899 : test_GetForm_args(tctx, b, handle, form_name, 1, &info),
2900 : "failed to get set form");
2901 :
2902 80 : torture_assert_int_equal(tctx, info.info1.size.width, add_info.info1->size.width, "width mismatch");
2903 : }
2904 :
2905 288 : if (!W_ERROR_EQUAL(expected_add_result, WERR_INVALID_PARAMETER)) {
2906 240 : torture_assert(tctx,
2907 : test_EnumForms_find_one(tctx, b, handle, print_server, form_name),
2908 : "Newly added form not found in enum call");
2909 : }
2910 :
2911 288 : torture_assert(tctx,
2912 : test_DeleteForm(tctx, b, handle, form_name, expected_delete_result),
2913 : "failed to delete form");
2914 :
2915 288 : return true;
2916 : }
2917 :
2918 48 : static bool test_Forms(struct torture_context *tctx,
2919 : struct dcerpc_binding_handle *b,
2920 : struct policy_handle *handle,
2921 : bool print_server,
2922 : const char *printer_name,
2923 : struct dcerpc_binding_handle *winreg_handle,
2924 : struct policy_handle *hive_handle)
2925 : {
2926 0 : const struct spoolss_FormSize size = {
2927 : .width = 50,
2928 : .height = 25
2929 : };
2930 0 : const struct spoolss_FormArea area = {
2931 : .left = 5,
2932 : .top = 10,
2933 : .right = 45,
2934 : .bottom = 15
2935 : };
2936 0 : int i;
2937 :
2938 0 : struct {
2939 : struct spoolss_AddFormInfo1 info1;
2940 : WERROR expected_add_result;
2941 : WERROR expected_delete_result;
2942 48 : } forms[] = {
2943 : {
2944 : .info1 = {
2945 : .flags = SPOOLSS_FORM_USER,
2946 : .form_name = "testform_user",
2947 : .size = size,
2948 : .area = area,
2949 : },
2950 : .expected_add_result = WERR_OK,
2951 : .expected_delete_result = WERR_OK
2952 : },
2953 : /*
2954 : weird, we can add a builtin form but we can never remove it
2955 : again - gd
2956 :
2957 : {
2958 : .info1 = {
2959 : .flags = SPOOLSS_FORM_BUILTIN,
2960 : .form_name = "testform_builtin",
2961 : .size = size,
2962 : .area = area,
2963 : },
2964 : .expected_add_result = WERR_OK,
2965 : .expected_delete_result = WERR_INVALID_PARAMETER,
2966 : },
2967 : */
2968 : {
2969 : .info1 = {
2970 : .flags = SPOOLSS_FORM_PRINTER,
2971 : .form_name = "testform_printer",
2972 : .size = size,
2973 : .area = area,
2974 : },
2975 : .expected_add_result = WERR_OK,
2976 : .expected_delete_result = WERR_OK
2977 : },
2978 : {
2979 : .info1 = {
2980 : .flags = SPOOLSS_FORM_USER,
2981 : .form_name = "Letter",
2982 : .size = size,
2983 : .area = area,
2984 : },
2985 : .expected_add_result = WERR_FILE_EXISTS,
2986 : .expected_delete_result = WERR_INVALID_PARAMETER
2987 : },
2988 : {
2989 : .info1 = {
2990 : .flags = SPOOLSS_FORM_BUILTIN,
2991 : .form_name = "Letter",
2992 : .size = size,
2993 : .area = area,
2994 : },
2995 : .expected_add_result = WERR_FILE_EXISTS,
2996 : .expected_delete_result = WERR_INVALID_PARAMETER
2997 : },
2998 : {
2999 : .info1 = {
3000 : .flags = SPOOLSS_FORM_PRINTER,
3001 : .form_name = "Letter",
3002 : .size = size,
3003 : .area = area,
3004 : },
3005 : .expected_add_result = WERR_FILE_EXISTS,
3006 : .expected_delete_result = WERR_INVALID_PARAMETER
3007 : },
3008 : {
3009 : .info1 = {
3010 : .flags = 12345,
3011 : .form_name = "invalid_flags",
3012 : .size = size,
3013 : .area = area,
3014 : },
3015 : .expected_add_result = WERR_INVALID_PARAMETER,
3016 : .expected_delete_result = WERR_INVALID_FORM_NAME
3017 : }
3018 :
3019 : };
3020 :
3021 336 : for (i=0; i < ARRAY_SIZE(forms); i++) {
3022 288 : torture_assert(tctx,
3023 : test_Forms_args(tctx, b, handle, print_server, printer_name,
3024 : winreg_handle, hive_handle,
3025 : forms[i].info1.form_name,
3026 : &forms[i].info1,
3027 : forms[i].expected_add_result,
3028 : forms[i].expected_delete_result),
3029 : talloc_asprintf(tctx, "failed to test form '%s'", forms[i].info1.form_name));
3030 : }
3031 :
3032 48 : return true;
3033 : }
3034 :
3035 4 : static bool test_EnumPorts_old(struct torture_context *tctx,
3036 : void *private_data)
3037 : {
3038 0 : struct test_spoolss_context *ctx =
3039 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
3040 :
3041 0 : NTSTATUS status;
3042 0 : struct spoolss_EnumPorts r;
3043 0 : uint32_t needed;
3044 0 : uint32_t count;
3045 0 : union spoolss_PortInfo *info;
3046 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
3047 4 : struct dcerpc_binding_handle *b = p->binding_handle;
3048 :
3049 4 : r.in.servername = talloc_asprintf(tctx, "\\\\%s",
3050 : dcerpc_server_name(p));
3051 4 : r.in.level = 2;
3052 4 : r.in.buffer = NULL;
3053 4 : r.in.offered = 0;
3054 4 : r.out.needed = &needed;
3055 4 : r.out.count = &count;
3056 4 : r.out.info = &info;
3057 :
3058 4 : torture_comment(tctx, "Testing EnumPorts\n");
3059 :
3060 4 : status = dcerpc_spoolss_EnumPorts_r(b, tctx, &r);
3061 :
3062 4 : torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
3063 :
3064 4 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3065 4 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
3066 4 : r.in.buffer = &blob;
3067 4 : r.in.offered = needed;
3068 :
3069 4 : status = dcerpc_spoolss_EnumPorts_r(b, tctx, &r);
3070 4 : torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
3071 4 : torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
3072 :
3073 4 : torture_assert(tctx, info, "No ports returned");
3074 : }
3075 :
3076 4 : torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
3077 :
3078 4 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, 2, count, needed, 4);
3079 :
3080 4 : return true;
3081 : }
3082 :
3083 4 : static bool test_AddPort(struct torture_context *tctx,
3084 : void *private_data)
3085 : {
3086 0 : struct test_spoolss_context *ctx =
3087 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
3088 :
3089 0 : NTSTATUS status;
3090 0 : struct spoolss_AddPort r;
3091 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
3092 4 : struct dcerpc_binding_handle *b = p->binding_handle;
3093 :
3094 4 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s",
3095 : dcerpc_server_name(p));
3096 4 : r.in.unknown = 0;
3097 4 : r.in.monitor_name = "foo";
3098 :
3099 4 : torture_comment(tctx, "Testing AddPort\n");
3100 :
3101 4 : status = dcerpc_spoolss_AddPort_r(b, tctx, &r);
3102 :
3103 4 : torture_assert_ntstatus_ok(tctx, status, "AddPort failed");
3104 :
3105 : /* win2k3 returns WERR_NOT_SUPPORTED */
3106 :
3107 : #if 0
3108 :
3109 : if (!W_ERROR_IS_OK(r.out.result)) {
3110 : printf("AddPort failed - %s\n", win_errstr(r.out.result));
3111 : return false;
3112 : }
3113 :
3114 : #endif
3115 :
3116 4 : return true;
3117 : }
3118 :
3119 1984 : static bool test_GetJob_args(struct torture_context *tctx,
3120 : struct dcerpc_binding_handle *b,
3121 : struct policy_handle *handle,
3122 : uint32_t job_id,
3123 : uint32_t level,
3124 : union spoolss_JobInfo *info_p)
3125 : {
3126 0 : NTSTATUS status;
3127 0 : struct spoolss_GetJob r;
3128 0 : union spoolss_JobInfo info;
3129 0 : uint32_t needed;
3130 :
3131 1984 : r.in.handle = handle;
3132 1984 : r.in.job_id = job_id;
3133 1984 : r.in.level = level;
3134 1984 : r.in.buffer = NULL;
3135 1984 : r.in.offered = 0;
3136 1984 : r.out.needed = &needed;
3137 1984 : r.out.info = &info;
3138 :
3139 1984 : torture_comment(tctx, "Testing GetJob(%d), level %d\n", job_id, r.in.level);
3140 :
3141 1984 : status = dcerpc_spoolss_GetJob_r(b, tctx, &r);
3142 1984 : torture_assert_ntstatus_ok(tctx, status, "GetJob failed");
3143 1984 : if (level == 0) {
3144 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "Unexpected return code");
3145 : }
3146 :
3147 1984 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3148 64 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
3149 64 : r.in.buffer = &blob;
3150 64 : r.in.offered = needed;
3151 :
3152 64 : status = dcerpc_spoolss_GetJob_r(b, tctx, &r);
3153 64 : torture_assert_ntstatus_ok(tctx, status, "GetJob failed");
3154 : }
3155 :
3156 1984 : torture_assert_werr_ok(tctx, r.out.result, "GetJob failed");
3157 64 : torture_assert(tctx, r.out.info, "No job info returned");
3158 :
3159 64 : CHECK_NEEDED_SIZE_LEVEL(spoolss_JobInfo, r.out.info, r.in.level, needed, 4);
3160 :
3161 64 : if (info_p) {
3162 64 : *info_p = *r.out.info;
3163 : }
3164 :
3165 64 : return true;
3166 : }
3167 :
3168 : #if 0
3169 : static bool test_GetJob(struct torture_context *tctx,
3170 : struct dcerpc_binding_handle *b,
3171 : struct policy_handle *handle,
3172 : uint32_t job_id)
3173 : {
3174 : uint32_t levels[] = {0, 1, 2 /* 3, 4 */};
3175 : uint32_t i;
3176 :
3177 : for (i=0; i < ARRAY_SIZE(levels); i++) {
3178 : torture_assert(tctx,
3179 : test_GetJob_args(tctx, b, handle, job_id, levels[i], NULL),
3180 : "GetJob failed");
3181 : }
3182 :
3183 : return true;
3184 : }
3185 : #endif
3186 :
3187 640 : static bool test_SetJob(struct torture_context *tctx,
3188 : struct dcerpc_binding_handle *b,
3189 : struct policy_handle *handle,
3190 : uint32_t job_id,
3191 : struct spoolss_JobInfoContainer *ctr,
3192 : enum spoolss_JobControl command)
3193 : {
3194 0 : NTSTATUS status;
3195 0 : struct spoolss_SetJob r;
3196 :
3197 640 : r.in.handle = handle;
3198 640 : r.in.job_id = job_id;
3199 640 : r.in.ctr = ctr;
3200 640 : r.in.command = command;
3201 :
3202 640 : switch (command) {
3203 32 : case SPOOLSS_JOB_CONTROL_PAUSE:
3204 32 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_PAUSE\n", job_id);
3205 32 : break;
3206 32 : case SPOOLSS_JOB_CONTROL_RESUME:
3207 32 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESUME\n", job_id);
3208 32 : break;
3209 0 : case SPOOLSS_JOB_CONTROL_CANCEL:
3210 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_CANCEL\n", job_id);
3211 0 : break;
3212 0 : case SPOOLSS_JOB_CONTROL_RESTART:
3213 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESTART\n", job_id);
3214 0 : break;
3215 544 : case SPOOLSS_JOB_CONTROL_DELETE:
3216 544 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_DELETE\n", job_id);
3217 544 : break;
3218 0 : case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER:
3219 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER\n", job_id);
3220 0 : break;
3221 0 : case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED:
3222 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED\n", job_id);
3223 0 : break;
3224 0 : case SPOOLSS_JOB_CONTROL_RETAIN:
3225 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RETAIN\n", job_id);
3226 0 : break;
3227 0 : case SPOOLSS_JOB_CONTROL_RELEASE:
3228 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RELEASE\n", job_id);
3229 0 : break;
3230 32 : default:
3231 32 : torture_comment(tctx, "Testing SetJob(%d)\n", job_id);
3232 32 : break;
3233 : }
3234 :
3235 640 : status = dcerpc_spoolss_SetJob_r(b, tctx, &r);
3236 640 : torture_assert_ntstatus_ok(tctx, status, "SetJob failed");
3237 640 : torture_assert_werr_ok(tctx, r.out.result, "SetJob failed");
3238 :
3239 402 : return true;
3240 : }
3241 :
3242 8 : static bool test_AddJob(struct torture_context *tctx,
3243 : struct dcerpc_binding_handle *b,
3244 : struct policy_handle *handle)
3245 : {
3246 0 : NTSTATUS status;
3247 0 : struct spoolss_AddJob r;
3248 0 : uint32_t needed;
3249 :
3250 8 : r.in.level = 0;
3251 8 : r.in.handle = handle;
3252 8 : r.in.offered = 0;
3253 8 : r.out.needed = &needed;
3254 8 : r.in.buffer = r.out.buffer = NULL;
3255 :
3256 8 : torture_comment(tctx, "Testing AddJob\n");
3257 :
3258 8 : status = dcerpc_spoolss_AddJob_r(b, tctx, &r);
3259 8 : torture_assert_ntstatus_ok(tctx, status, "AddJob failed");
3260 8 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "AddJob failed");
3261 :
3262 8 : r.in.level = 1;
3263 :
3264 8 : status = dcerpc_spoolss_AddJob_r(b, tctx, &r);
3265 8 : torture_assert_ntstatus_ok(tctx, status, "AddJob failed");
3266 8 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER, "AddJob failed");
3267 :
3268 8 : return true;
3269 : }
3270 :
3271 :
3272 68 : static bool test_EnumJobs_args(struct torture_context *tctx,
3273 : struct dcerpc_binding_handle *b,
3274 : struct policy_handle *handle,
3275 : uint32_t level,
3276 : WERROR werr_expected,
3277 : uint32_t *count_p,
3278 : union spoolss_JobInfo **info_p)
3279 : {
3280 0 : NTSTATUS status;
3281 0 : struct spoolss_EnumJobs r;
3282 0 : uint32_t needed;
3283 0 : uint32_t count;
3284 0 : union spoolss_JobInfo *info;
3285 :
3286 68 : r.in.handle = handle;
3287 68 : r.in.firstjob = 0;
3288 68 : r.in.numjobs = 0xffffffff;
3289 68 : r.in.level = level;
3290 68 : r.in.buffer = NULL;
3291 68 : r.in.offered = 0;
3292 68 : r.out.needed = &needed;
3293 68 : r.out.count = &count;
3294 68 : r.out.info = &info;
3295 :
3296 68 : torture_comment(tctx, "Testing EnumJobs level %d\n", level);
3297 :
3298 68 : status = dcerpc_spoolss_EnumJobs_r(b, tctx, &r);
3299 :
3300 68 : torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
3301 :
3302 68 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3303 16 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
3304 16 : r.in.buffer = &blob;
3305 16 : r.in.offered = needed;
3306 :
3307 16 : status = dcerpc_spoolss_EnumJobs_r(b, tctx, &r);
3308 :
3309 16 : torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
3310 16 : torture_assert_werr_equal(tctx, r.out.result, werr_expected,
3311 : "EnumJobs failed");
3312 16 : torture_assert(tctx, info, "No jobs returned");
3313 :
3314 16 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumJobs, *r.out.info, r.in.level, count, needed, 4);
3315 :
3316 : } else {
3317 52 : torture_assert_werr_equal(tctx, r.out.result, werr_expected,
3318 : "EnumJobs failed");
3319 : }
3320 :
3321 68 : if (count_p) {
3322 68 : *count_p = count;
3323 : }
3324 68 : if (info_p) {
3325 68 : *info_p = info;
3326 : }
3327 :
3328 68 : return true;
3329 : }
3330 :
3331 0 : static bool test_JobPropertiesEnum(struct torture_context *tctx,
3332 : struct dcerpc_binding_handle *b,
3333 : struct policy_handle *handle,
3334 : uint32_t job_id)
3335 : {
3336 0 : struct spoolss_EnumJobNamedProperties r;
3337 0 : uint32_t pcProperties = 0;
3338 0 : struct spoolss_PrintNamedProperty *ppProperties = NULL;
3339 :
3340 0 : r.in.hPrinter = handle;
3341 0 : r.in.JobId = job_id;
3342 0 : r.out.pcProperties = &pcProperties;
3343 0 : r.out.ppProperties = &ppProperties;
3344 :
3345 0 : torture_comment(tctx, "Testing EnumJobNamedProperties(%d)\n", job_id);
3346 :
3347 0 : torture_assert_ntstatus_ok(tctx,
3348 : dcerpc_spoolss_EnumJobNamedProperties_r(b, tctx, &r),
3349 : "spoolss_EnumJobNamedProperties failed");
3350 0 : torture_assert_werr_ok(tctx, r.out.result,
3351 : "spoolss_EnumJobNamedProperties failed");
3352 :
3353 0 : return true;
3354 : }
3355 :
3356 0 : static bool test_JobPropertySet(struct torture_context *tctx,
3357 : struct dcerpc_binding_handle *b,
3358 : struct policy_handle *handle,
3359 : uint32_t job_id,
3360 : struct spoolss_PrintNamedProperty *property)
3361 : {
3362 0 : struct spoolss_SetJobNamedProperty r;
3363 :
3364 0 : r.in.hPrinter = handle;
3365 0 : r.in.JobId = job_id;
3366 0 : r.in.pProperty = property;
3367 :
3368 0 : torture_comment(tctx, "Testing SetJobNamedProperty(%d) %s - %d\n",
3369 : job_id, property->propertyName,
3370 0 : property->propertyValue.ePropertyType);
3371 :
3372 0 : torture_assert_ntstatus_ok(tctx,
3373 : dcerpc_spoolss_SetJobNamedProperty_r(b, tctx, &r),
3374 : "spoolss_SetJobNamedProperty failed");
3375 0 : torture_assert_werr_ok(tctx, r.out.result,
3376 : "spoolss_SetJobNamedProperty failed");
3377 :
3378 0 : return true;
3379 : }
3380 :
3381 0 : static bool test_JobPropertyGetValue(struct torture_context *tctx,
3382 : struct dcerpc_binding_handle *b,
3383 : struct policy_handle *handle,
3384 : uint32_t job_id,
3385 : const char *property_name,
3386 : struct spoolss_PrintPropertyValue *value)
3387 : {
3388 0 : struct spoolss_GetJobNamedPropertyValue r;
3389 :
3390 0 : r.in.hPrinter = handle;
3391 0 : r.in.JobId = job_id;
3392 0 : r.in.pszName = property_name;
3393 0 : r.out.pValue = value;
3394 :
3395 0 : torture_comment(tctx, "Testing GetJobNamedPropertyValue(%d) %s\n",
3396 : job_id, property_name);
3397 :
3398 0 : torture_assert_ntstatus_ok(tctx,
3399 : dcerpc_spoolss_GetJobNamedPropertyValue_r(b, tctx, &r),
3400 : "spoolss_GetJobNamedPropertyValue failed");
3401 0 : torture_assert_werr_ok(tctx, r.out.result,
3402 : "spoolss_GetJobNamedPropertyValue failed");
3403 :
3404 0 : return true;
3405 : }
3406 :
3407 0 : static bool test_JobPropertyDelete(struct torture_context *tctx,
3408 : struct dcerpc_binding_handle *b,
3409 : struct policy_handle *handle,
3410 : uint32_t job_id,
3411 : const char *property_name)
3412 : {
3413 0 : struct spoolss_DeleteJobNamedProperty r;
3414 :
3415 0 : r.in.hPrinter = handle;
3416 0 : r.in.JobId = job_id;
3417 0 : r.in.pszName = property_name;
3418 :
3419 0 : torture_comment(tctx, "Testing DeleteJobNamedProperty(%d) %s\n",
3420 : job_id, property_name);
3421 :
3422 0 : torture_assert_ntstatus_ok(tctx,
3423 : dcerpc_spoolss_DeleteJobNamedProperty_r(b, tctx, &r),
3424 : "spoolss_DeleteJobNamedProperty failed");
3425 0 : torture_assert_werr_ok(tctx, r.out.result,
3426 : "spoolss_DeleteJobNamedProperty failed");
3427 :
3428 0 : return true;
3429 : }
3430 :
3431 640 : static bool test_DoPrintTest_add_one_job_common(struct torture_context *tctx,
3432 : struct dcerpc_binding_handle *b,
3433 : struct policy_handle *handle,
3434 : const char *document_name,
3435 : const char *datatype,
3436 : uint32_t *job_id)
3437 : {
3438 0 : NTSTATUS status;
3439 0 : struct spoolss_StartDocPrinter s;
3440 0 : struct spoolss_DocumentInfoCtr info_ctr;
3441 0 : struct spoolss_DocumentInfo1 info1;
3442 0 : struct spoolss_StartPagePrinter sp;
3443 0 : struct spoolss_WritePrinter w;
3444 0 : struct spoolss_EndPagePrinter ep;
3445 0 : struct spoolss_EndDocPrinter e;
3446 0 : int i;
3447 0 : uint32_t num_written;
3448 :
3449 640 : torture_comment(tctx, "Testing StartDocPrinter\n");
3450 :
3451 640 : s.in.handle = handle;
3452 640 : s.in.info_ctr = &info_ctr;
3453 640 : s.out.job_id = job_id;
3454 :
3455 640 : info1.document_name = document_name;
3456 640 : info1.output_file = NULL;
3457 640 : info1.datatype = datatype;
3458 :
3459 640 : info_ctr.level = 1;
3460 640 : info_ctr.info.info1 = &info1;
3461 :
3462 640 : status = dcerpc_spoolss_StartDocPrinter_r(b, tctx, &s);
3463 640 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_StartDocPrinter failed");
3464 640 : torture_assert_werr_ok(tctx, s.out.result, "StartDocPrinter failed");
3465 :
3466 2560 : for (i=1; i < 4; i++) {
3467 0 : union spoolss_JobInfo ginfo;
3468 0 : bool ok;
3469 :
3470 1920 : torture_comment(tctx, "Testing StartPagePrinter: Page[%d], JobId[%d]\n", i, *job_id);
3471 :
3472 1920 : sp.in.handle = handle;
3473 :
3474 1920 : status = dcerpc_spoolss_StartPagePrinter_r(b, tctx, &sp);
3475 1920 : torture_assert_ntstatus_ok(tctx, status,
3476 : "dcerpc_spoolss_StartPagePrinter failed");
3477 1920 : torture_assert_werr_ok(tctx, sp.out.result, "StartPagePrinter failed");
3478 :
3479 1920 : ok = test_GetJob_args(tctx, b, handle, *job_id, 1, &ginfo);
3480 1920 : if (!ok) {
3481 1920 : torture_comment(tctx, "test_GetJob failed for JobId[%d]\n", *job_id);
3482 : }
3483 :
3484 1920 : torture_comment(tctx, "Testing WritePrinter: Page[%d], JobId[%d]\n", i, *job_id);
3485 :
3486 1920 : w.in.handle = handle;
3487 1920 : w.in.data = data_blob_string_const(talloc_asprintf(tctx,"TortureTestPage: %d\nData\n",i));
3488 1920 : w.out.num_written = &num_written;
3489 :
3490 1920 : status = dcerpc_spoolss_WritePrinter_r(b, tctx, &w);
3491 1920 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_WritePrinter failed");
3492 1920 : torture_assert_werr_ok(tctx, w.out.result, "WritePrinter failed");
3493 :
3494 1920 : torture_comment(tctx, "Testing EndPagePrinter: Page[%d], JobId[%d]\n", i, *job_id);
3495 :
3496 1920 : ep.in.handle = handle;
3497 :
3498 1920 : status = dcerpc_spoolss_EndPagePrinter_r(b, tctx, &ep);
3499 1920 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndPagePrinter failed");
3500 1920 : torture_assert_werr_ok(tctx, ep.out.result, "EndPagePrinter failed");
3501 : }
3502 :
3503 640 : torture_comment(tctx, "Testing EndDocPrinter: JobId[%d]\n", *job_id);
3504 :
3505 640 : e.in.handle = handle;
3506 :
3507 640 : status = dcerpc_spoolss_EndDocPrinter_r(b, tctx, &e);
3508 640 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndDocPrinter failed");
3509 640 : torture_assert_werr_ok(tctx, e.out.result, "EndDocPrinter failed");
3510 :
3511 352 : return true;
3512 : }
3513 :
3514 416 : static bool test_DoPrintTest_add_one_job(struct torture_context *tctx,
3515 : struct dcerpc_binding_handle *b,
3516 : struct policy_handle *handle,
3517 : const char *document_name,
3518 : uint32_t *job_id)
3519 : {
3520 416 : test_DoPrintTest_add_one_job_common(tctx, b, handle, document_name, "RAW", job_id);
3521 :
3522 416 : return true;
3523 : }
3524 :
3525 224 : static bool test_DoPrintTest_add_one_job_v4(struct torture_context *tctx,
3526 : struct dcerpc_binding_handle *b,
3527 : struct policy_handle *handle,
3528 : const char *document_name,
3529 : uint32_t *job_id)
3530 : {
3531 224 : test_DoPrintTest_add_one_job_common(tctx, b, handle, document_name, "XPS_PASS", job_id);
3532 :
3533 224 : return true;
3534 : }
3535 :
3536 :
3537 8 : static bool test_DoPrintTest_check_jobs(struct torture_context *tctx,
3538 : struct dcerpc_binding_handle *b,
3539 : struct policy_handle *handle,
3540 : uint32_t num_jobs,
3541 : uint32_t *job_ids)
3542 : {
3543 0 : uint32_t count;
3544 8 : union spoolss_JobInfo *info = NULL;
3545 0 : int i;
3546 :
3547 8 : torture_assert(tctx,
3548 : test_AddJob(tctx, b, handle),
3549 : "AddJob failed");
3550 :
3551 8 : torture_assert(tctx,
3552 : test_EnumJobs_args(tctx, b, handle, 1, WERR_OK, &count, &info),
3553 : "EnumJobs level 1 failed");
3554 :
3555 8 : torture_assert_int_equal(tctx, count, num_jobs, "unexpected number of jobs in queue");
3556 :
3557 36 : for (i=0; i < num_jobs; i++) {
3558 0 : union spoolss_JobInfo ginfo;
3559 0 : const char *document_name;
3560 32 : const char *new_document_name = "any_other_docname";
3561 0 : struct spoolss_JobInfoContainer ctr;
3562 0 : struct spoolss_SetJobInfo1 info1;
3563 :
3564 32 : torture_assert_int_equal(tctx, info[i].info1.job_id, job_ids[i], "job id mismatch");
3565 :
3566 32 : torture_assert(tctx,
3567 : test_GetJob_args(tctx, b, handle, info[i].info1.job_id, 1, &ginfo),
3568 : "failed to call test_GetJob");
3569 :
3570 32 : torture_assert_int_equal(tctx, ginfo.info1.job_id, info[i].info1.job_id, "job id mismatch");
3571 :
3572 32 : document_name = ginfo.info1.document_name;
3573 :
3574 32 : info1.job_id = ginfo.info1.job_id;
3575 32 : info1.printer_name = ginfo.info1.printer_name;
3576 32 : info1.server_name = ginfo.info1.server_name;
3577 32 : info1.user_name = ginfo.info1.user_name;
3578 32 : info1.document_name = new_document_name;
3579 32 : info1.data_type = ginfo.info1.data_type;
3580 32 : info1.text_status = ginfo.info1.text_status;
3581 32 : info1.status = ginfo.info1.status;
3582 32 : info1.priority = ginfo.info1.priority;
3583 32 : info1.position = ginfo.info1.position;
3584 32 : info1.total_pages = ginfo.info1.total_pages;
3585 32 : info1.pages_printed = ginfo.info1.pages_printed;
3586 32 : info1.submitted = ginfo.info1.submitted;
3587 :
3588 32 : ctr.level = 1;
3589 32 : ctr.info.info1 = &info1;
3590 :
3591 32 : torture_assert(tctx,
3592 : test_SetJob(tctx, b, handle, info[i].info1.job_id, &ctr, 0),
3593 : "failed to call test_SetJob level 1");
3594 :
3595 32 : torture_assert(tctx,
3596 : test_GetJob_args(tctx, b, handle, info[i].info1.job_id, 1, &ginfo),
3597 : "failed to call test_GetJob");
3598 :
3599 32 : if (strequal(ginfo.info1.document_name, document_name)) {
3600 22 : torture_warning(tctx,
3601 : "document_name did *NOT* change from '%s' to '%s'\n",
3602 : document_name, new_document_name);
3603 : }
3604 : }
3605 :
3606 36 : for (i=0; i < num_jobs; i++) {
3607 32 : if (!test_SetJob(tctx, b, handle, info[i].info1.job_id, NULL, SPOOLSS_JOB_CONTROL_PAUSE)) {
3608 0 : torture_warning(tctx, "failed to pause printjob\n");
3609 : }
3610 32 : if (!test_SetJob(tctx, b, handle, info[i].info1.job_id, NULL, SPOOLSS_JOB_CONTROL_RESUME)) {
3611 0 : torture_warning(tctx, "failed to resume printjob\n");
3612 : }
3613 : }
3614 :
3615 4 : return true;
3616 : }
3617 :
3618 28 : static bool test_DoPrintTest(struct torture_context *tctx,
3619 : struct dcerpc_binding_handle *b,
3620 : struct policy_handle *handle)
3621 : {
3622 28 : bool ret = true;
3623 28 : uint32_t num_jobs = 8;
3624 0 : uint32_t *job_ids;
3625 0 : int i;
3626 :
3627 28 : torture_comment(tctx, "Testing real print operations\n");
3628 :
3629 28 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
3630 :
3631 252 : for (i=0; i < num_jobs; i++) {
3632 224 : ret &= test_DoPrintTest_add_one_job(tctx, b, handle, "TorturePrintJob", &job_ids[i]);
3633 : }
3634 :
3635 252 : for (i=0; i < num_jobs; i++) {
3636 224 : ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
3637 : }
3638 :
3639 252 : for (i=0; i < num_jobs; i++) {
3640 224 : ret &= test_DoPrintTest_add_one_job_v4(tctx, b, handle, "TorturePrintJob v4", &job_ids[i]);
3641 : }
3642 :
3643 252 : for (i=0; i < num_jobs; i++) {
3644 224 : ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
3645 : }
3646 :
3647 28 : if (ret == true) {
3648 14 : torture_comment(tctx, "real print operations test succeeded\n\n");
3649 : }
3650 :
3651 28 : return ret;
3652 : }
3653 :
3654 8 : static bool test_DoPrintTest_extended(struct torture_context *tctx,
3655 : struct dcerpc_binding_handle *b,
3656 : struct policy_handle *handle)
3657 : {
3658 8 : bool ret = true;
3659 8 : uint32_t num_jobs = 8;
3660 0 : uint32_t *job_ids;
3661 0 : int i;
3662 8 : torture_comment(tctx, "Testing real print operations (extended)\n");
3663 :
3664 8 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
3665 :
3666 72 : for (i=0; i < num_jobs; i++) {
3667 64 : ret &= test_DoPrintTest_add_one_job(tctx, b, handle, "TorturePrintJob", &job_ids[i]);
3668 : }
3669 :
3670 8 : ret &= test_DoPrintTest_check_jobs(tctx, b, handle, num_jobs, job_ids);
3671 :
3672 72 : for (i=0; i < num_jobs; i++) {
3673 64 : ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
3674 : }
3675 :
3676 8 : if (ret == true) {
3677 4 : torture_comment(tctx, "real print operations (extended) test succeeded\n\n");
3678 : }
3679 :
3680 8 : return ret;
3681 : }
3682 :
3683 0 : static bool test_JobPrintProperties_equal(struct torture_context *tctx,
3684 : struct spoolss_PrintPropertyValue *got,
3685 : struct spoolss_PrintNamedProperty *exp)
3686 : {
3687 0 : torture_assert_int_equal(tctx,
3688 : got->ePropertyType,
3689 : exp->propertyValue.ePropertyType,
3690 : "ePropertyType");
3691 :
3692 0 : switch (exp->propertyValue.ePropertyType) {
3693 0 : case kRpcPropertyTypeString:
3694 0 : torture_assert_str_equal(tctx,
3695 : got->value.propertyString,
3696 : exp->propertyValue.value.propertyString,
3697 : "propertyString");
3698 0 : break;
3699 0 : case kRpcPropertyTypeInt32:
3700 0 : torture_assert_int_equal(tctx,
3701 : got->value.propertyInt32,
3702 : exp->propertyValue.value.propertyInt32,
3703 : "propertyInt32");
3704 0 : break;
3705 0 : case kRpcPropertyTypeInt64:
3706 0 : torture_assert_u64_equal(tctx,
3707 : got->value.propertyInt64,
3708 : exp->propertyValue.value.propertyInt64,
3709 : "propertyInt64");
3710 0 : break;
3711 0 : case kRpcPropertyTypeByte:
3712 0 : torture_assert_int_equal(tctx,
3713 : got->value.propertyByte,
3714 : exp->propertyValue.value.propertyByte,
3715 : "propertyByte");
3716 0 : break;
3717 0 : case kRpcPropertyTypeBuffer:
3718 0 : torture_assert_int_equal(tctx,
3719 : got->value.propertyBlob.cbBuf,
3720 : exp->propertyValue.value.propertyBlob.cbBuf,
3721 : "propertyBlob.cbBuf");
3722 0 : torture_assert_mem_equal(tctx,
3723 : got->value.propertyBlob.pBuf,
3724 : exp->propertyValue.value.propertyBlob.pBuf,
3725 : exp->propertyValue.value.propertyBlob.cbBuf,
3726 : "propertyBlob.pBuf");
3727 :
3728 0 : break;
3729 :
3730 : }
3731 :
3732 0 : return true;
3733 : }
3734 :
3735 0 : static bool test_JobPrintProperties(struct torture_context *tctx,
3736 : struct dcerpc_binding_handle *b,
3737 : struct policy_handle *handle,
3738 : uint32_t job_id)
3739 : {
3740 0 : struct spoolss_PrintNamedProperty in;
3741 0 : struct spoolss_PrintPropertyValue out;
3742 0 : int i;
3743 0 : DATA_BLOB blob = data_blob_string_const("blob");
3744 0 : struct {
3745 : const char *property_name;
3746 : enum spoolss_EPrintPropertyType type;
3747 : union spoolss_PrintPropertyValueUnion value;
3748 : WERROR expected_result;
3749 0 : } tests[] = {
3750 : {
3751 : .property_name = "torture_property_string",
3752 : .type = kRpcPropertyTypeString,
3753 : .value.propertyString = "torture_property_value_string",
3754 : },{
3755 : .property_name = "torture_property_int32",
3756 : .type = kRpcPropertyTypeInt32,
3757 : .value.propertyInt32 = 42,
3758 : },{
3759 : .property_name = "torture_property_int64",
3760 : .type = kRpcPropertyTypeInt64,
3761 : .value.propertyInt64 = 0xaffe,
3762 : },{
3763 : .property_name = "torture_property_byte",
3764 : .type = kRpcPropertyTypeByte,
3765 : .value.propertyByte = 0xab,
3766 : },{
3767 : .property_name = "torture_property_buffer",
3768 : .type = kRpcPropertyTypeBuffer,
3769 0 : .value.propertyBlob.cbBuf = blob.length,
3770 0 : .value.propertyBlob.pBuf = blob.data,
3771 : }
3772 : };
3773 :
3774 0 : torture_assert(tctx,
3775 : test_JobPropertiesEnum(tctx, b, handle, job_id),
3776 : "failed to enum properties");
3777 :
3778 0 : for (i=0; i <ARRAY_SIZE(tests); i++) {
3779 :
3780 0 : in.propertyName = tests[i].property_name;
3781 0 : in.propertyValue.ePropertyType = tests[i].type;
3782 0 : in.propertyValue.value = tests[i].value;
3783 :
3784 0 : torture_assert(tctx,
3785 : test_JobPropertySet(tctx, b, handle, job_id, &in),
3786 : "failed to set property");
3787 :
3788 0 : torture_assert(tctx,
3789 : test_JobPropertyGetValue(tctx, b, handle, job_id, in.propertyName, &out),
3790 : "failed to get property");
3791 :
3792 0 : torture_assert(tctx,
3793 : test_JobPrintProperties_equal(tctx, &out, &in),
3794 : "property unequal");
3795 :
3796 0 : torture_assert(tctx,
3797 : test_JobPropertiesEnum(tctx, b, handle, job_id),
3798 : "failed to enum properties");
3799 :
3800 0 : torture_assert(tctx,
3801 : test_JobPropertyDelete(tctx, b, handle, job_id, in.propertyName),
3802 : "failed to delete job property");
3803 : }
3804 :
3805 0 : torture_assert(tctx,
3806 : test_JobPropertiesEnum(tctx, b, handle, job_id),
3807 : "failed to enum properties");
3808 :
3809 0 : return true;
3810 : }
3811 :
3812 0 : static bool test_DoPrintTest_properties(struct torture_context *tctx,
3813 : struct dcerpc_binding_handle *b,
3814 : struct policy_handle *handle)
3815 : {
3816 0 : uint32_t num_jobs = 8;
3817 0 : uint32_t *job_ids;
3818 0 : int i;
3819 0 : torture_comment(tctx, "Testing real print operations (properties)\n");
3820 :
3821 0 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
3822 :
3823 0 : for (i=0; i < num_jobs; i++) {
3824 0 : torture_assert(tctx,
3825 : test_DoPrintTest_add_one_job(tctx, b, handle, "TorturePrintJob", &job_ids[i]),
3826 : "failed to create print job");
3827 : }
3828 :
3829 0 : for (i=0; i < num_jobs; i++) {
3830 0 : torture_assert(tctx,
3831 : test_JobPrintProperties(tctx, b, handle, job_ids[i]),
3832 : "failed to test job properties");
3833 : }
3834 :
3835 :
3836 0 : for (i=0; i < num_jobs; i++) {
3837 0 : torture_assert(tctx,
3838 : test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE),
3839 : "failed to delete printjob");
3840 : }
3841 :
3842 0 : torture_comment(tctx, "real print operations (properties) test succeeded\n\n");
3843 :
3844 0 : return true;
3845 : }
3846 :
3847 52 : static bool test_PausePrinter(struct torture_context *tctx,
3848 : struct dcerpc_binding_handle *b,
3849 : struct policy_handle *handle)
3850 : {
3851 0 : NTSTATUS status;
3852 0 : struct spoolss_SetPrinter r;
3853 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
3854 0 : struct spoolss_DevmodeContainer devmode_ctr;
3855 0 : struct sec_desc_buf secdesc_ctr;
3856 :
3857 52 : info_ctr.level = 0;
3858 52 : info_ctr.info.info0 = NULL;
3859 :
3860 52 : ZERO_STRUCT(devmode_ctr);
3861 52 : ZERO_STRUCT(secdesc_ctr);
3862 :
3863 52 : r.in.handle = handle;
3864 52 : r.in.info_ctr = &info_ctr;
3865 52 : r.in.devmode_ctr = &devmode_ctr;
3866 52 : r.in.secdesc_ctr = &secdesc_ctr;
3867 52 : r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
3868 :
3869 52 : torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
3870 :
3871 52 : status = dcerpc_spoolss_SetPrinter_r(b, tctx, &r);
3872 :
3873 52 : torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
3874 :
3875 52 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
3876 :
3877 52 : return true;
3878 : }
3879 :
3880 40 : static bool test_ResumePrinter(struct torture_context *tctx,
3881 : struct dcerpc_binding_handle *b,
3882 : struct policy_handle *handle)
3883 : {
3884 0 : NTSTATUS status;
3885 0 : struct spoolss_SetPrinter r;
3886 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
3887 0 : struct spoolss_DevmodeContainer devmode_ctr;
3888 0 : struct sec_desc_buf secdesc_ctr;
3889 :
3890 40 : info_ctr.level = 0;
3891 40 : info_ctr.info.info0 = NULL;
3892 :
3893 40 : ZERO_STRUCT(devmode_ctr);
3894 40 : ZERO_STRUCT(secdesc_ctr);
3895 :
3896 40 : r.in.handle = handle;
3897 40 : r.in.info_ctr = &info_ctr;
3898 40 : r.in.devmode_ctr = &devmode_ctr;
3899 40 : r.in.secdesc_ctr = &secdesc_ctr;
3900 40 : r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
3901 :
3902 40 : torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
3903 :
3904 40 : status = dcerpc_spoolss_SetPrinter_r(b, tctx, &r);
3905 :
3906 40 : torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
3907 :
3908 40 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
3909 :
3910 40 : return true;
3911 : }
3912 :
3913 12 : static bool test_printer_purge(struct torture_context *tctx,
3914 : struct dcerpc_binding_handle *b,
3915 : struct policy_handle *handle)
3916 : {
3917 0 : NTSTATUS status;
3918 0 : struct spoolss_SetPrinter r;
3919 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
3920 0 : struct spoolss_DevmodeContainer devmode_ctr;
3921 0 : struct sec_desc_buf secdesc_ctr;
3922 :
3923 12 : info_ctr.level = 0;
3924 12 : info_ctr.info.info0 = NULL;
3925 :
3926 12 : ZERO_STRUCT(devmode_ctr);
3927 12 : ZERO_STRUCT(secdesc_ctr);
3928 :
3929 12 : r.in.handle = handle;
3930 12 : r.in.info_ctr = &info_ctr;
3931 12 : r.in.devmode_ctr = &devmode_ctr;
3932 12 : r.in.secdesc_ctr = &secdesc_ctr;
3933 12 : r.in.command = SPOOLSS_PRINTER_CONTROL_PURGE;
3934 :
3935 12 : torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PURGE\n");
3936 :
3937 12 : status = dcerpc_spoolss_SetPrinter_r(b, tctx, &r);
3938 12 : torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
3939 12 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
3940 :
3941 12 : return true;
3942 : }
3943 :
3944 232 : static bool test_GetPrinterData_checktype(struct torture_context *tctx,
3945 : struct dcerpc_binding_handle *b,
3946 : struct policy_handle *handle,
3947 : const char *value_name,
3948 : enum winreg_Type *expected_type,
3949 : enum winreg_Type *type_p,
3950 : uint8_t **data_p,
3951 : uint32_t *needed_p)
3952 : {
3953 0 : NTSTATUS status;
3954 0 : struct spoolss_GetPrinterData r;
3955 0 : uint32_t needed;
3956 0 : enum winreg_Type type;
3957 0 : union spoolss_PrinterData data;
3958 :
3959 232 : r.in.handle = handle;
3960 232 : r.in.value_name = value_name;
3961 232 : r.in.offered = 0;
3962 232 : r.out.needed = &needed;
3963 232 : r.out.type = &type;
3964 232 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
3965 :
3966 232 : torture_comment(tctx, "Testing GetPrinterData(%s)\n", r.in.value_name);
3967 :
3968 232 : status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &r);
3969 232 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
3970 :
3971 232 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
3972 232 : if (expected_type) {
3973 84 : torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
3974 : }
3975 232 : r.in.offered = needed;
3976 232 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
3977 232 : status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &r);
3978 232 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
3979 : }
3980 :
3981 232 : torture_assert_werr_ok(tctx, r.out.result,
3982 : talloc_asprintf(tctx, "GetPrinterData(%s) failed", r.in.value_name));
3983 :
3984 232 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, needed, 1);
3985 :
3986 232 : if (type_p) {
3987 224 : *type_p = type;
3988 : }
3989 :
3990 232 : if (data_p) {
3991 232 : *data_p = r.out.data;
3992 : }
3993 :
3994 232 : if (needed_p) {
3995 232 : *needed_p = needed;
3996 : }
3997 :
3998 232 : return true;
3999 : }
4000 :
4001 140 : static bool test_GetPrinterData(struct torture_context *tctx,
4002 : struct dcerpc_binding_handle *b,
4003 : struct policy_handle *handle,
4004 : const char *value_name,
4005 : enum winreg_Type *type_p,
4006 : uint8_t **data_p,
4007 : uint32_t *needed_p)
4008 : {
4009 140 : return test_GetPrinterData_checktype(tctx, b, handle, value_name,
4010 : NULL, type_p, data_p, needed_p);
4011 : }
4012 :
4013 1368 : static bool test_GetPrinterDataEx_checktype(struct torture_context *tctx,
4014 : struct dcerpc_pipe *p,
4015 : struct policy_handle *handle,
4016 : const char *key_name,
4017 : const char *value_name,
4018 : enum winreg_Type *expected_type,
4019 : enum winreg_Type *type_p,
4020 : uint8_t **data_p,
4021 : uint32_t *needed_p)
4022 : {
4023 0 : NTSTATUS status;
4024 0 : struct spoolss_GetPrinterDataEx r;
4025 0 : enum winreg_Type type;
4026 0 : uint32_t needed;
4027 0 : union spoolss_PrinterData data;
4028 1368 : struct dcerpc_binding_handle *b = p->binding_handle;
4029 :
4030 1368 : r.in.handle = handle;
4031 1368 : r.in.key_name = key_name;
4032 1368 : r.in.value_name = value_name;
4033 1368 : r.in.offered = 0;
4034 1368 : r.out.type = &type;
4035 1368 : r.out.needed = &needed;
4036 1368 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
4037 :
4038 1368 : torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)\n",
4039 : r.in.key_name, r.in.value_name);
4040 :
4041 1368 : status = dcerpc_spoolss_GetPrinterDataEx_r(b, tctx, &r);
4042 1368 : if (!NT_STATUS_IS_OK(status)) {
4043 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
4044 0 : torture_skip(tctx, "GetPrinterDataEx not supported by server\n");
4045 : }
4046 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
4047 : }
4048 :
4049 1368 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
4050 1332 : if (expected_type) {
4051 972 : torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
4052 : }
4053 1332 : r.in.offered = needed;
4054 1332 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
4055 1332 : status = dcerpc_spoolss_GetPrinterDataEx_r(b, tctx, &r);
4056 1332 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
4057 : }
4058 :
4059 1368 : torture_assert_werr_ok(tctx, r.out.result,
4060 : talloc_asprintf(tctx, "GetPrinterDataEx(%s - %s) failed", r.in.key_name, r.in.value_name));
4061 :
4062 1368 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, needed, 1);
4063 :
4064 1368 : if (type_p) {
4065 1368 : *type_p = type;
4066 : }
4067 :
4068 1368 : if (data_p) {
4069 1368 : *data_p = r.out.data;
4070 : }
4071 :
4072 1368 : if (needed_p) {
4073 1368 : *needed_p = needed;
4074 : }
4075 :
4076 1368 : return true;
4077 : }
4078 :
4079 360 : static bool test_GetPrinterDataEx(struct torture_context *tctx,
4080 : struct dcerpc_pipe *p,
4081 : struct policy_handle *handle,
4082 : const char *key_name,
4083 : const char *value_name,
4084 : enum winreg_Type *type_p,
4085 : uint8_t **data_p,
4086 : uint32_t *needed_p)
4087 : {
4088 360 : return test_GetPrinterDataEx_checktype(tctx, p, handle, key_name, value_name,
4089 : NULL, type_p, data_p, needed_p);
4090 : }
4091 :
4092 68 : static bool test_get_environment(struct torture_context *tctx,
4093 : struct dcerpc_binding_handle *b,
4094 : struct policy_handle *handle,
4095 : const char **architecture)
4096 : {
4097 0 : DATA_BLOB blob;
4098 0 : enum winreg_Type type;
4099 0 : uint8_t *data;
4100 0 : uint32_t needed;
4101 :
4102 68 : torture_assert(tctx,
4103 : test_GetPrinterData(tctx, b, handle, "Architecture", &type, &data, &needed),
4104 : "failed to get Architecture");
4105 :
4106 68 : torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");
4107 :
4108 68 : blob = data_blob_const(data, needed);
4109 68 : *architecture = reg_val_data_string(tctx, REG_SZ, blob);
4110 :
4111 68 : return true;
4112 : }
4113 :
4114 4 : static bool test_GetPrinterData_list(struct torture_context *tctx,
4115 : void *private_data)
4116 : {
4117 0 : struct test_spoolss_context *ctx =
4118 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
4119 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
4120 4 : struct dcerpc_binding_handle *b = p->binding_handle;
4121 4 : const char *list[] = {
4122 : "W3SvcInstalled",
4123 : "BeepEnabled",
4124 : "EventLog",
4125 : /* "NetPopup", not on w2k8 */
4126 : /* "NetPopupToComputer", not on w2k8 */
4127 : "MajorVersion",
4128 : "MinorVersion",
4129 : "DefaultSpoolDirectory",
4130 : "Architecture",
4131 : "DsPresent",
4132 : "OSVersion",
4133 : /* "OSVersionEx", not on s3 */
4134 : "DNSMachineName"
4135 : };
4136 0 : int i;
4137 :
4138 44 : for (i=0; i < ARRAY_SIZE(list); i++) {
4139 40 : enum winreg_Type type = REG_NONE;
4140 40 : enum winreg_Type type_ex1 = REG_NONE;
4141 40 : enum winreg_Type type_ex2 = REG_NONE;
4142 0 : uint8_t *data;
4143 40 : uint8_t *data_ex1 = NULL;
4144 40 : uint8_t *data_ex2 = NULL;
4145 0 : uint32_t needed;
4146 40 : uint32_t needed_ex1 = 0;
4147 40 : uint32_t needed_ex2 = 0;
4148 :
4149 40 : torture_assert(tctx, test_GetPrinterData(tctx, b, &ctx->server_handle, list[i], &type, &data, &needed),
4150 : talloc_asprintf(tctx, "GetPrinterData failed on %s\n", list[i]));
4151 40 : torture_assert(tctx, test_GetPrinterDataEx(tctx, p, &ctx->server_handle, "random_string", list[i], &type_ex1, &data_ex1, &needed_ex1),
4152 : talloc_asprintf(tctx, "GetPrinterDataEx failed on %s\n", list[i]));
4153 40 : torture_assert(tctx, test_GetPrinterDataEx(tctx, p, &ctx->server_handle, "", list[i], &type_ex2, &data_ex2, &needed_ex2),
4154 : talloc_asprintf(tctx, "GetPrinterDataEx failed on %s\n", list[i]));
4155 40 : torture_assert_int_equal(tctx, type, type_ex1, "type mismatch");
4156 40 : torture_assert_int_equal(tctx, type, type_ex2, "type mismatch");
4157 40 : torture_assert_int_equal(tctx, needed, needed_ex1, "needed mismatch");
4158 40 : torture_assert_int_equal(tctx, needed, needed_ex2, "needed mismatch");
4159 40 : torture_assert_mem_equal(tctx, data, data_ex1, needed, "data mismatch");
4160 40 : torture_assert_mem_equal(tctx, data, data_ex2, needed, "data mismatch");
4161 : }
4162 :
4163 4 : return true;
4164 : }
4165 :
4166 152 : static bool test_EnumPrinterData(struct torture_context *tctx,
4167 : struct dcerpc_pipe *p,
4168 : struct policy_handle *handle,
4169 : uint32_t enum_index,
4170 : uint32_t value_offered,
4171 : uint32_t data_offered,
4172 : enum winreg_Type *type_p,
4173 : uint32_t *value_needed_p,
4174 : uint32_t *data_needed_p,
4175 : const char **value_name_p,
4176 : uint8_t **data_p,
4177 : WERROR *result_p)
4178 : {
4179 0 : struct spoolss_EnumPrinterData r;
4180 0 : uint32_t data_needed;
4181 0 : uint32_t value_needed;
4182 0 : enum winreg_Type type;
4183 152 : struct dcerpc_binding_handle *b = p->binding_handle;
4184 :
4185 152 : r.in.handle = handle;
4186 152 : r.in.enum_index = enum_index;
4187 152 : r.in.value_offered = value_offered;
4188 152 : r.in.data_offered = data_offered;
4189 152 : r.out.data_needed = &data_needed;
4190 152 : r.out.value_needed = &value_needed;
4191 152 : r.out.type = &type;
4192 152 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.data_offered);
4193 152 : r.out.value_name = talloc_zero_array(tctx, const char, r.in.value_offered);
4194 :
4195 152 : torture_comment(tctx, "Testing EnumPrinterData(%d)\n", enum_index);
4196 :
4197 152 : torture_assert_ntstatus_ok(tctx,
4198 : dcerpc_spoolss_EnumPrinterData_r(b, tctx, &r),
4199 : "EnumPrinterData failed");
4200 :
4201 152 : if (type_p) {
4202 124 : *type_p = type;
4203 : }
4204 152 : if (value_needed_p) {
4205 152 : *value_needed_p = value_needed;
4206 : }
4207 152 : if (data_needed_p) {
4208 152 : *data_needed_p = data_needed;
4209 : }
4210 152 : if (value_name_p) {
4211 124 : *value_name_p = r.out.value_name;
4212 : }
4213 152 : if (data_p) {
4214 124 : *data_p = r.out.data;
4215 : }
4216 152 : if (result_p) {
4217 152 : *result_p = r.out.result;
4218 : }
4219 :
4220 152 : return true;
4221 : }
4222 :
4223 :
4224 20 : static bool test_EnumPrinterData_all(struct torture_context *tctx,
4225 : struct dcerpc_pipe *p,
4226 : struct policy_handle *handle)
4227 : {
4228 20 : uint32_t enum_index = 0;
4229 0 : enum winreg_Type type;
4230 0 : uint32_t value_needed;
4231 0 : uint32_t data_needed;
4232 0 : uint8_t *data;
4233 0 : const char *value_name;
4234 0 : WERROR result;
4235 :
4236 20 : torture_comment(tctx, "Testing EnumPrinterData\n");
4237 :
4238 0 : do {
4239 20 : torture_assert(tctx,
4240 : test_EnumPrinterData(tctx, p, handle, enum_index, 0, 0,
4241 : &type, &value_needed, &data_needed,
4242 : &value_name, &data, &result),
4243 : "EnumPrinterData failed");
4244 :
4245 20 : if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS)) {
4246 0 : break;
4247 : }
4248 :
4249 20 : torture_assert(tctx,
4250 : test_EnumPrinterData(tctx, p, handle, enum_index, value_needed, data_needed,
4251 : &type, &value_needed, &data_needed,
4252 : &value_name, &data, &result),
4253 : "EnumPrinterData failed");
4254 :
4255 20 : if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS)) {
4256 20 : break;
4257 : }
4258 :
4259 0 : enum_index++;
4260 :
4261 0 : } while (W_ERROR_IS_OK(result));
4262 :
4263 20 : torture_comment(tctx, "EnumPrinterData test succeeded\n");
4264 :
4265 20 : return true;
4266 : }
4267 :
4268 1316 : static bool test_EnumPrinterDataEx(struct torture_context *tctx,
4269 : struct dcerpc_binding_handle *b,
4270 : struct policy_handle *handle,
4271 : const char *key_name,
4272 : uint32_t *count_p,
4273 : struct spoolss_PrinterEnumValues **info_p)
4274 : {
4275 0 : struct spoolss_EnumPrinterDataEx r;
4276 0 : struct spoolss_PrinterEnumValues *info;
4277 0 : uint32_t needed;
4278 0 : uint32_t count;
4279 :
4280 1316 : r.in.handle = handle;
4281 1316 : r.in.key_name = key_name;
4282 1316 : r.in.offered = 0;
4283 1316 : r.out.needed = &needed;
4284 1316 : r.out.count = &count;
4285 1316 : r.out.info = &info;
4286 :
4287 1316 : torture_comment(tctx, "Testing EnumPrinterDataEx(%s)\n", key_name);
4288 :
4289 1316 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &r),
4290 : "EnumPrinterDataEx failed");
4291 1316 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
4292 1256 : r.in.offered = needed;
4293 1256 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &r),
4294 : "EnumPrinterDataEx failed");
4295 : }
4296 :
4297 1316 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDataEx failed");
4298 :
4299 1316 : CHECK_NEEDED_SIZE_ENUM(spoolss_EnumPrinterDataEx, info, count, needed, 1);
4300 :
4301 1316 : if (count_p) {
4302 1228 : *count_p = count;
4303 : }
4304 1316 : if (info_p) {
4305 1228 : *info_p = info;
4306 : }
4307 :
4308 1316 : return true;
4309 : }
4310 :
4311 : static bool test_SetPrinterData(struct torture_context *tctx,
4312 : struct dcerpc_binding_handle *b,
4313 : struct policy_handle *handle,
4314 : const char *value_name,
4315 : enum winreg_Type type,
4316 : uint8_t *data,
4317 : uint32_t offered);
4318 : static bool test_DeletePrinterData(struct torture_context *tctx,
4319 : struct dcerpc_binding_handle *b,
4320 : struct policy_handle *handle,
4321 : const char *value_name);
4322 :
4323 28 : static bool test_EnumPrinterData_consistency(struct torture_context *tctx,
4324 : struct dcerpc_pipe *p,
4325 : struct policy_handle *handle)
4326 : {
4327 0 : uint32_t count;
4328 0 : struct spoolss_PrinterEnumValues *info;
4329 0 : int i;
4330 0 : uint32_t value_needed, data_needed;
4331 0 : uint32_t value_offered, data_offered;
4332 0 : WERROR result;
4333 28 : struct dcerpc_binding_handle *b = p->binding_handle;
4334 :
4335 0 : enum winreg_Type type;
4336 0 : DATA_BLOB blob;
4337 :
4338 28 : torture_comment(tctx, "Testing EnumPrinterData vs EnumPrinterDataEx consistency\n");
4339 :
4340 28 : torture_assert(tctx, push_reg_sz(tctx, &blob, "torture_data1"), "");
4341 28 : type = REG_SZ;
4342 :
4343 28 : torture_assert(tctx,
4344 : test_SetPrinterData(tctx, b, handle, "torture_value1", type, blob.data, blob.length),
4345 : "SetPrinterData failed");
4346 :
4347 28 : blob = data_blob_string_const("torture_data2");
4348 :
4349 28 : torture_assert(tctx,
4350 : test_SetPrinterData(tctx, b, handle, "torture_value2", REG_BINARY, blob.data, blob.length),
4351 : "SetPrinterData failed");
4352 :
4353 28 : blob = data_blob_talloc(tctx, NULL, 4);
4354 28 : SIVAL(blob.data, 0, 0x11223344);
4355 :
4356 28 : torture_assert(tctx,
4357 : test_SetPrinterData(tctx, b, handle, "torture_value3", type, blob.data, blob.length),
4358 : "SetPrinterData failed");
4359 :
4360 28 : torture_assert(tctx,
4361 : test_EnumPrinterDataEx(tctx, b, handle, "PrinterDriverData", &count, &info),
4362 : "failed to call EnumPrinterDataEx");
4363 :
4364 : /* get the max sizes for value and data */
4365 :
4366 28 : torture_assert(tctx,
4367 : test_EnumPrinterData(tctx, p, handle, 0, 0, 0,
4368 : NULL, &value_needed, &data_needed,
4369 : NULL, NULL, &result),
4370 : "EnumPrinterData failed");
4371 28 : torture_assert_werr_ok(tctx, result, "unexpected result");
4372 :
4373 : /* check if the reply from the EnumPrinterData really matches max values */
4374 :
4375 112 : for (i=0; i < count; i++) {
4376 84 : if (info[i].value_name_len > value_needed) {
4377 0 : torture_fail(tctx,
4378 : talloc_asprintf(tctx,
4379 : "EnumPrinterDataEx gave a reply with value length %d which is larger then expected max value length %d from EnumPrinterData",
4380 : info[i].value_name_len, value_needed));
4381 : }
4382 84 : if (info[i].data_length > data_needed) {
4383 0 : torture_fail(tctx,
4384 : talloc_asprintf(tctx,
4385 : "EnumPrinterDataEx gave a reply with data length %d which is larger then expected max data length %d from EnumPrinterData",
4386 : info[i].data_length, data_needed));
4387 : }
4388 : }
4389 :
4390 : /* assuming that both EnumPrinterData and EnumPrinterDataEx do either
4391 : * sort or not sort the replies by value name, we should be able to do
4392 : * the following entry comparison */
4393 :
4394 28 : data_offered = data_needed;
4395 28 : value_offered = value_needed;
4396 :
4397 112 : for (i=0; i < count; i++) {
4398 :
4399 0 : const char *value_name;
4400 0 : uint8_t *data;
4401 :
4402 84 : torture_assert(tctx,
4403 : test_EnumPrinterData(tctx, p, handle, i, value_offered, data_offered,
4404 : &type, &value_needed, &data_needed,
4405 : &value_name, &data, &result),
4406 : "EnumPrinterData failed");
4407 :
4408 84 : if (i -1 == count) {
4409 0 : torture_assert_werr_equal(tctx, result, WERR_NO_MORE_ITEMS,
4410 : "unexpected result");
4411 0 : break;
4412 : } else {
4413 84 : torture_assert_werr_ok(tctx, result, "unexpected result");
4414 : }
4415 :
4416 84 : torture_assert_int_equal(tctx, type, info[i].type, "type mismatch");
4417 84 : torture_assert_int_equal(tctx, value_needed, info[i].value_name_len, "value name length mismatch");
4418 84 : torture_assert_str_equal(tctx, value_name, info[i].value_name, "value name mismatch");
4419 84 : torture_assert_int_equal(tctx, data_needed, info[i].data_length, "data length mismatch");
4420 84 : torture_assert_mem_equal(tctx, data, info[i].data->data, info[i].data_length, "data mismatch");
4421 : }
4422 :
4423 28 : torture_assert(tctx,
4424 : test_DeletePrinterData(tctx, b, handle, "torture_value1"),
4425 : "DeletePrinterData failed");
4426 28 : torture_assert(tctx,
4427 : test_DeletePrinterData(tctx, b, handle, "torture_value2"),
4428 : "DeletePrinterData failed");
4429 28 : torture_assert(tctx,
4430 : test_DeletePrinterData(tctx, b, handle, "torture_value3"),
4431 : "DeletePrinterData failed");
4432 :
4433 28 : torture_comment(tctx, "EnumPrinterData vs EnumPrinterDataEx consistency test succeeded\n\n");
4434 :
4435 28 : return true;
4436 : }
4437 :
4438 168 : static bool test_DeletePrinterData(struct torture_context *tctx,
4439 : struct dcerpc_binding_handle *b,
4440 : struct policy_handle *handle,
4441 : const char *value_name)
4442 : {
4443 0 : NTSTATUS status;
4444 0 : struct spoolss_DeletePrinterData r;
4445 :
4446 168 : r.in.handle = handle;
4447 168 : r.in.value_name = value_name;
4448 :
4449 168 : torture_comment(tctx, "Testing DeletePrinterData(%s)\n",
4450 : r.in.value_name);
4451 :
4452 168 : status = dcerpc_spoolss_DeletePrinterData_r(b, tctx, &r);
4453 :
4454 168 : torture_assert_ntstatus_ok(tctx, status, "DeletePrinterData failed");
4455 168 : torture_assert_werr_ok(tctx, r.out.result, "DeletePrinterData failed");
4456 :
4457 168 : return true;
4458 : }
4459 :
4460 1200 : static bool test_DeletePrinterDataEx(struct torture_context *tctx,
4461 : struct dcerpc_binding_handle *b,
4462 : struct policy_handle *handle,
4463 : const char *key_name,
4464 : const char *value_name)
4465 : {
4466 0 : struct spoolss_DeletePrinterDataEx r;
4467 :
4468 1200 : r.in.handle = handle;
4469 1200 : r.in.key_name = key_name;
4470 1200 : r.in.value_name = value_name;
4471 :
4472 1200 : torture_comment(tctx, "Testing DeletePrinterDataEx(%s - %s)\n",
4473 : r.in.key_name, r.in.value_name);
4474 :
4475 1200 : torture_assert_ntstatus_ok(tctx,
4476 : dcerpc_spoolss_DeletePrinterDataEx_r(b, tctx, &r),
4477 : "DeletePrinterDataEx failed");
4478 1200 : torture_assert_werr_ok(tctx, r.out.result,
4479 : "DeletePrinterDataEx failed");
4480 :
4481 1200 : return true;
4482 : }
4483 :
4484 216 : static bool test_DeletePrinterKey(struct torture_context *tctx,
4485 : struct dcerpc_binding_handle *b,
4486 : struct policy_handle *handle,
4487 : const char *key_name)
4488 : {
4489 0 : struct spoolss_DeletePrinterKey r;
4490 :
4491 216 : r.in.handle = handle;
4492 216 : r.in.key_name = key_name;
4493 :
4494 216 : torture_comment(tctx, "Testing DeletePrinterKey(%s)\n", r.in.key_name);
4495 :
4496 216 : if (strequal(key_name, "") && !torture_setting_bool(tctx, "dangerous", false)) {
4497 0 : torture_skip(tctx, "not wiping out printer registry - enable dangerous tests to use\n");
4498 : return true;
4499 : }
4500 :
4501 216 : torture_assert_ntstatus_ok(tctx,
4502 : dcerpc_spoolss_DeletePrinterKey_r(b, tctx, &r),
4503 : "DeletePrinterKey failed");
4504 216 : torture_assert_werr_ok(tctx, r.out.result,
4505 : "DeletePrinterKey failed");
4506 :
4507 216 : return true;
4508 : }
4509 :
4510 48 : static bool test_winreg_OpenHKLM(struct torture_context *tctx,
4511 : struct dcerpc_binding_handle *b,
4512 : struct policy_handle *handle)
4513 : {
4514 0 : struct winreg_OpenHKLM r;
4515 :
4516 48 : r.in.system_name = NULL;
4517 48 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4518 48 : r.out.handle = handle;
4519 :
4520 48 : torture_comment(tctx, "Testing winreg_OpenHKLM\n");
4521 :
4522 48 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenHKLM_r(b, tctx, &r), "OpenHKLM failed");
4523 48 : torture_assert_werr_ok(tctx, r.out.result, "OpenHKLM failed");
4524 :
4525 48 : return true;
4526 : }
4527 :
4528 3626 : static void init_winreg_String(struct winreg_String *name, const char *s)
4529 : {
4530 3626 : name->name = s;
4531 3626 : if (s) {
4532 3626 : name->name_len = 2 * (strlen_m(s) + 1);
4533 3626 : name->name_size = name->name_len;
4534 : } else {
4535 0 : name->name_len = 0;
4536 0 : name->name_size = 0;
4537 : }
4538 3626 : }
4539 :
4540 320 : static bool test_winreg_OpenKey_opts(struct torture_context *tctx,
4541 : struct dcerpc_binding_handle *b,
4542 : struct policy_handle *hive_handle,
4543 : const char *keyname,
4544 : uint32_t options,
4545 : struct policy_handle *key_handle)
4546 : {
4547 0 : struct winreg_OpenKey r;
4548 :
4549 320 : r.in.parent_handle = hive_handle;
4550 320 : init_winreg_String(&r.in.keyname, keyname);
4551 320 : r.in.options = options;
4552 320 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4553 320 : r.out.handle = key_handle;
4554 :
4555 320 : torture_comment(tctx, "Testing winreg_OpenKey(%s)\n", keyname);
4556 :
4557 320 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r), "OpenKey failed");
4558 320 : torture_assert_werr_ok(tctx, r.out.result, "OpenKey failed");
4559 :
4560 320 : return true;
4561 : }
4562 :
4563 320 : static bool test_winreg_OpenKey(struct torture_context *tctx,
4564 : struct dcerpc_binding_handle *b,
4565 : struct policy_handle *hive_handle,
4566 : const char *keyname,
4567 : struct policy_handle *key_handle)
4568 : {
4569 320 : return test_winreg_OpenKey_opts(tctx, b, hive_handle, keyname,
4570 : REG_OPTION_NON_VOLATILE, key_handle);
4571 : }
4572 :
4573 368 : static bool test_winreg_CloseKey(struct torture_context *tctx,
4574 : struct dcerpc_binding_handle *b,
4575 : struct policy_handle *handle)
4576 : {
4577 0 : struct winreg_CloseKey r;
4578 :
4579 368 : r.in.handle = handle;
4580 368 : r.out.handle = handle;
4581 :
4582 368 : torture_comment(tctx, "Testing winreg_CloseKey\n");
4583 :
4584 368 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r), "CloseKey failed");
4585 368 : torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
4586 :
4587 368 : return true;
4588 : }
4589 :
4590 3306 : bool test_winreg_QueryValue(struct torture_context *tctx,
4591 : struct dcerpc_binding_handle *b,
4592 : struct policy_handle *handle,
4593 : const char *value_name,
4594 : enum winreg_Type *type_p,
4595 : uint32_t *data_size_p,
4596 : uint32_t *data_length_p,
4597 : uint8_t **data_p)
4598 : {
4599 0 : struct winreg_QueryValue r;
4600 3306 : enum winreg_Type type = REG_NONE;
4601 3306 : uint32_t data_size = 0;
4602 3306 : uint32_t data_length = 0;
4603 0 : struct winreg_String valuename;
4604 3306 : uint8_t *data = NULL;
4605 :
4606 3306 : init_winreg_String(&valuename, value_name);
4607 :
4608 3306 : data = talloc_zero_array(tctx, uint8_t, 0);
4609 :
4610 3306 : r.in.handle = handle;
4611 3306 : r.in.value_name = &valuename;
4612 3306 : r.in.type = &type;
4613 3306 : r.in.data_size = &data_size;
4614 3306 : r.in.data_length = &data_length;
4615 3306 : r.in.data = data;
4616 3306 : r.out.type = &type;
4617 3306 : r.out.data = data;
4618 3306 : r.out.data_size = &data_size;
4619 3306 : r.out.data_length = &data_length;
4620 :
4621 3306 : torture_comment(tctx, "Testing winreg_QueryValue(%s)\n", value_name);
4622 :
4623 3306 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
4624 3306 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
4625 3222 : *r.in.data_size = *r.out.data_size;
4626 3222 : data = talloc_zero_array(tctx, uint8_t, *r.in.data_size);
4627 3222 : r.in.data = data;
4628 3222 : r.out.data = data;
4629 3222 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
4630 : }
4631 3306 : torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
4632 :
4633 3306 : if (type_p) {
4634 3306 : *type_p = *r.out.type;
4635 : }
4636 3306 : if (data_size_p) {
4637 3306 : *data_size_p = *r.out.data_size;
4638 : }
4639 3306 : if (data_length_p) {
4640 3306 : *data_length_p = *r.out.data_length;
4641 : }
4642 3306 : if (data_p) {
4643 3306 : *data_p = r.out.data;
4644 : }
4645 :
4646 3306 : return true;
4647 : }
4648 :
4649 248 : static bool test_winreg_query_printerdata(struct torture_context *tctx,
4650 : struct dcerpc_binding_handle *b,
4651 : struct policy_handle *handle,
4652 : const char *printer_name,
4653 : const char *key_name,
4654 : const char *value_name,
4655 : enum winreg_Type *w_type,
4656 : uint32_t *w_size,
4657 : uint32_t *w_length,
4658 : uint8_t **w_data)
4659 : {
4660 0 : const char *printer_key;
4661 0 : struct policy_handle key_handle;
4662 :
4663 248 : printer_key = talloc_asprintf(tctx, "%s\\%s\\%s",
4664 : TOP_LEVEL_PRINT_PRINTERS_KEY, printer_name, key_name);
4665 :
4666 248 : torture_assert(tctx,
4667 : test_winreg_OpenKey(tctx, b, handle, printer_key, &key_handle), "");
4668 :
4669 248 : torture_assert(tctx,
4670 : test_winreg_QueryValue(tctx, b, &key_handle, value_name, w_type, w_size, w_length, w_data), "");
4671 :
4672 248 : torture_assert(tctx,
4673 : test_winreg_CloseKey(tctx, b, &key_handle), "");
4674 :
4675 248 : return true;
4676 : }
4677 :
4678 48 : static bool test_GetForm_winreg(struct torture_context *tctx,
4679 : struct dcerpc_binding_handle *b,
4680 : struct policy_handle *handle,
4681 : const char *key_name,
4682 : const char *form_name,
4683 : enum winreg_Type *w_type,
4684 : uint32_t *w_size,
4685 : uint32_t *w_length,
4686 : uint8_t **w_data)
4687 : {
4688 0 : struct policy_handle key_handle;
4689 :
4690 48 : torture_assert(tctx,
4691 : test_winreg_OpenKey(tctx, b, handle, key_name, &key_handle), "");
4692 :
4693 48 : torture_assert(tctx,
4694 : test_winreg_QueryValue(tctx, b, &key_handle, form_name, w_type, w_size, w_length, w_data), "");
4695 :
4696 48 : torture_assert(tctx,
4697 : test_winreg_CloseKey(tctx, b, &key_handle), "");
4698 :
4699 48 : return true;
4700 : }
4701 :
4702 8 : static bool test_winreg_symbolic_link(struct torture_context *tctx,
4703 : struct dcerpc_binding_handle *b,
4704 : struct policy_handle *handle,
4705 : const char *symlink_keyname,
4706 : const char *symlink_destination)
4707 : {
4708 : /* check if the first key is a symlink to the second key */
4709 :
4710 0 : enum winreg_Type w_type;
4711 0 : uint32_t w_size;
4712 0 : uint32_t w_length;
4713 0 : uint8_t *w_data;
4714 0 : struct policy_handle key_handle;
4715 0 : DATA_BLOB blob;
4716 0 : const char *str;
4717 :
4718 8 : if (torture_setting_bool(tctx, "samba3", false)) {
4719 8 : torture_skip(tctx, "skip winreg symlink test against samba");
4720 : }
4721 :
4722 0 : torture_assert(tctx,
4723 : test_winreg_OpenKey_opts(tctx, b, handle, symlink_keyname, REG_OPTION_OPEN_LINK, &key_handle),
4724 : "failed to open key link");
4725 :
4726 0 : torture_assert(tctx,
4727 : test_winreg_QueryValue(tctx, b, &key_handle,
4728 : "SymbolicLinkValue",
4729 : &w_type, &w_size, &w_length, &w_data),
4730 : "failed to query for 'SymbolicLinkValue' attribute");
4731 :
4732 0 : torture_assert_int_equal(tctx, w_type, REG_LINK, "unexpected type");
4733 :
4734 0 : blob = data_blob(w_data, w_size);
4735 0 : str = reg_val_data_string(tctx, REG_SZ, blob);
4736 :
4737 0 : torture_assert_str_equal(tctx, str, symlink_destination, "unexpected symlink target string");
4738 :
4739 0 : torture_assert(tctx,
4740 : test_winreg_CloseKey(tctx, b, &key_handle),
4741 : "failed to close key link");
4742 :
4743 0 : return true;
4744 : }
4745 :
4746 16 : static const char *strip_unc(const char *unc)
4747 : {
4748 0 : char *name;
4749 :
4750 16 : if (!unc) {
4751 0 : return NULL;
4752 : }
4753 :
4754 16 : if (unc[0] == '\\' && unc[1] == '\\') {
4755 8 : unc +=2;
4756 : }
4757 :
4758 16 : name = strchr(unc, '\\');
4759 16 : if (name) {
4760 8 : return name+1;
4761 : }
4762 :
4763 8 : return unc;
4764 : }
4765 :
4766 8 : static bool test_GetPrinterInfo_winreg(struct torture_context *tctx,
4767 : struct dcerpc_binding_handle *b,
4768 : struct policy_handle *handle,
4769 : const char *printer_name,
4770 : struct dcerpc_binding_handle *winreg_handle,
4771 : struct policy_handle *hive_handle)
4772 : {
4773 0 : union spoolss_PrinterInfo info;
4774 8 : const char *keys[] = {
4775 : TOP_LEVEL_CONTROL_PRINTERS_KEY,
4776 : TOP_LEVEL_PRINT_PRINTERS_KEY
4777 : };
4778 0 : int i;
4779 0 : const char *printername, *sharename;
4780 :
4781 8 : torture_comment(tctx, "Testing Printer Info and winreg consistency\n");
4782 :
4783 8 : torture_assert(tctx,
4784 : test_GetPrinter_level(tctx, b, handle, 2, &info),
4785 : "failed to get printer info level 2");
4786 :
4787 8 : printername = strip_unc(info.info2.printername);
4788 8 : sharename = strip_unc(info.info2.sharename);
4789 :
4790 : #define test_sz(wname, iname) \
4791 : do {\
4792 : DATA_BLOB blob;\
4793 : const char *str;\
4794 : enum winreg_Type w_type;\
4795 : uint32_t w_size;\
4796 : uint32_t w_length;\
4797 : uint8_t *w_data;\
4798 : torture_assert(tctx,\
4799 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4800 : &w_type, &w_size, &w_length, &w_data),\
4801 : "failed to query winreg");\
4802 : torture_assert_int_equal(tctx, w_type, REG_SZ, "unexpected type");\
4803 : blob = data_blob(w_data, w_size);\
4804 : str = reg_val_data_string(tctx, REG_SZ, blob);\
4805 : if (w_size == 2 && iname == NULL) {\
4806 : /*torture_comment(tctx, "%s: \"\", %s: (null)\n", #wname, #iname);\ */\
4807 : } else {\
4808 : torture_assert_str_equal(tctx, str, iname,\
4809 : talloc_asprintf(tctx, "%s - %s mismatch", #wname, #iname));\
4810 : }\
4811 : } while(0);
4812 :
4813 : #define test_dword(wname, iname) \
4814 : do {\
4815 : uint32_t value;\
4816 : enum winreg_Type w_type;\
4817 : uint32_t w_size;\
4818 : uint32_t w_length;\
4819 : uint8_t *w_data;\
4820 : torture_assert(tctx,\
4821 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4822 : &w_type, &w_size, &w_length, &w_data),\
4823 : "failed to query winreg");\
4824 : torture_assert_int_equal(tctx, w_type, REG_DWORD, "unexpected type");\
4825 : torture_assert_int_equal(tctx, w_size, 4, "unexpected size");\
4826 : torture_assert_int_equal(tctx, w_length, 4, "unexpected length");\
4827 : value = IVAL(w_data, 0);\
4828 : torture_assert_int_equal(tctx, value, iname,\
4829 : talloc_asprintf(tctx, "%s - %s mismatch", #wname, #iname));\
4830 : } while(0);
4831 :
4832 : #define test_binary(wname, iname) \
4833 : do {\
4834 : enum winreg_Type w_type;\
4835 : uint32_t w_size;\
4836 : uint32_t w_length;\
4837 : uint8_t *w_data;\
4838 : torture_assert(tctx,\
4839 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4840 : &w_type, &w_size, &w_length, &w_data),\
4841 : "failed to query winreg");\
4842 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4843 : torture_assert_int_equal(tctx, w_size, iname.length, "unexpected length");\
4844 : torture_assert_mem_equal(tctx, w_data, iname.data, w_size, \
4845 : "binary unequal");\
4846 : } while(0);
4847 :
4848 :
4849 : #define test_dm(wname, iname) \
4850 : do {\
4851 : DATA_BLOB blob;\
4852 : struct spoolss_DeviceMode dm;\
4853 : enum ndr_err_code ndr_err;\
4854 : enum winreg_Type w_type;\
4855 : uint32_t w_size;\
4856 : uint32_t w_length;\
4857 : uint8_t *w_data;\
4858 : torture_assert(tctx,\
4859 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4860 : &w_type, &w_size, &w_length, &w_data),\
4861 : "failed to query winreg");\
4862 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4863 : blob = data_blob(w_data, w_size);\
4864 : ndr_err = ndr_pull_struct_blob(&blob, tctx, &dm,\
4865 : (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);\
4866 : torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall dm");\
4867 : torture_assert(tctx, test_devicemode_equal(tctx, &dm, iname),\
4868 : "dm unequal");\
4869 : } while(0);
4870 :
4871 : #define test_sd(wname, iname) \
4872 : do {\
4873 : DATA_BLOB blob;\
4874 : struct security_descriptor sd;\
4875 : enum ndr_err_code ndr_err;\
4876 : enum winreg_Type w_type;\
4877 : uint32_t w_size;\
4878 : uint32_t w_length;\
4879 : uint8_t *w_data;\
4880 : torture_assert(tctx,\
4881 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4882 : &w_type, &w_size, &w_length, &w_data),\
4883 : "failed to query winreg");\
4884 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4885 : blob = data_blob(w_data, w_size);\
4886 : ndr_err = ndr_pull_struct_blob(&blob, tctx, &sd,\
4887 : (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);\
4888 : torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall sd");\
4889 : torture_assert(tctx, test_security_descriptor_equal(tctx, &sd, iname),\
4890 : "sd unequal");\
4891 : } while(0);
4892 :
4893 : #define test_multi_sz(wname, iname) \
4894 : do {\
4895 : DATA_BLOB blob;\
4896 : const char **array;\
4897 : enum winreg_Type w_type;\
4898 : uint32_t w_size;\
4899 : uint32_t w_length;\
4900 : uint8_t *w_data;\
4901 : int i;\
4902 : torture_assert(tctx,\
4903 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4904 : &w_type, &w_size, &w_length, &w_data),\
4905 : "failed to query winreg");\
4906 : torture_assert_int_equal(tctx, w_type, REG_MULTI_SZ, "unexpected type");\
4907 : blob = data_blob(w_data, w_size);\
4908 : torture_assert(tctx, \
4909 : pull_reg_multi_sz(tctx, &blob, &array),\
4910 : "failed to pull multi sz");\
4911 : for (i=0; array[i] != NULL; i++) {\
4912 : torture_assert_str_equal(tctx, array[i], iname[i],\
4913 : talloc_asprintf(tctx, "%s - %s mismatch", #wname, iname[i]));\
4914 : }\
4915 : } while(0);
4916 :
4917 8 : if (!test_winreg_symbolic_link(tctx, winreg_handle, hive_handle,
4918 : TOP_LEVEL_CONTROL_PRINTERS_KEY,
4919 : "\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"))
4920 : {
4921 0 : torture_warning(tctx, "failed to check for winreg symlink");
4922 : }
4923 :
4924 24 : for (i=0; i < ARRAY_SIZE(keys); i++) {
4925 :
4926 0 : const char *printer_key;
4927 0 : struct policy_handle key_handle;
4928 :
4929 16 : printer_key = talloc_asprintf(tctx, "%s\\%s",
4930 : keys[i], printer_name);
4931 :
4932 16 : torture_assert(tctx,
4933 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle, printer_key, &key_handle), "");
4934 :
4935 16 : test_sz("Name", printername);
4936 16 : test_sz("Share Name", sharename);
4937 16 : test_sz("Port", info.info2.portname);
4938 16 : test_sz("Printer Driver", info.info2.drivername);
4939 16 : test_sz("Description", info.info2.comment);
4940 16 : test_sz("Location", info.info2.location);
4941 16 : test_sz("Separator File", info.info2.sepfile);
4942 16 : test_sz("Print Processor", info.info2.printprocessor);
4943 16 : test_sz("Datatype", info.info2.datatype);
4944 16 : test_sz("Parameters", info.info2.parameters);
4945 : /* winreg: 0, spoolss not */
4946 : /* test_dword("Attributes", info.info2.attributes); */
4947 16 : test_dword("Priority", info.info2.priority);
4948 16 : test_dword("Default Priority", info.info2.defaultpriority);
4949 : /* winreg: 60, spoolss: 0 */
4950 : /* test_dword("StartTime", info.info2.starttime); */
4951 : /* test_dword("UntilTime", info.info2.untiltime); */
4952 : /* winreg != spoolss */
4953 : /* test_dword("Status", info.info2.status); */
4954 16 : test_dm("Default DevMode", info.info2.devmode);
4955 16 : test_sd("Security", info.info2.secdesc);
4956 :
4957 16 : torture_assert(tctx,
4958 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
4959 : }
4960 :
4961 : #undef test_dm
4962 :
4963 8 : torture_comment(tctx, "Printer Info and winreg consistency test succeeded\n\n");
4964 :
4965 8 : return true;
4966 : }
4967 :
4968 4 : static bool test_GetPrintserverInfo_winreg(struct torture_context *tctx,
4969 : struct dcerpc_binding_handle *b,
4970 : struct policy_handle *handle,
4971 : struct dcerpc_binding_handle *winreg_handle,
4972 : struct policy_handle *hive_handle)
4973 : {
4974 0 : union spoolss_PrinterInfo info;
4975 0 : struct policy_handle key_handle;
4976 :
4977 4 : torture_comment(tctx,
4978 : "Testing Printserver Info and winreg consistency\n");
4979 :
4980 4 : torture_assert(tctx,
4981 : test_GetPrinter_level(tctx, b, handle, 3, &info),
4982 : "failed to get printer info level 2");
4983 :
4984 4 : torture_assert(tctx,
4985 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle,
4986 : TOP_LEVEL_CONTROL_KEY, &key_handle), "");
4987 :
4988 4 : test_sd("ServerSecurityDescriptor", info.info3.secdesc);
4989 :
4990 4 : torture_assert(tctx,
4991 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
4992 :
4993 : #undef test_sd
4994 :
4995 4 : torture_comment(tctx,
4996 : "Printserver Info and winreg consistency test succeeded\n\n");
4997 :
4998 4 : return true;
4999 : }
5000 :
5001 :
5002 4 : static bool test_PrintProcessors(struct torture_context *tctx,
5003 : struct dcerpc_binding_handle *b,
5004 : const char *environment,
5005 : struct dcerpc_binding_handle *winreg_handle,
5006 : struct policy_handle *hive_handle)
5007 : {
5008 0 : union spoolss_PrintProcessorInfo *info;
5009 0 : uint32_t count;
5010 0 : int i;
5011 :
5012 4 : torture_comment(tctx, "Testing Print Processor Info and winreg consistency\n");
5013 :
5014 4 : torture_assert(tctx,
5015 : test_EnumPrintProcessors_level(tctx, b, environment, 1, &count, &info, WERR_OK),
5016 : "failed to enum print processors level 1");
5017 :
5018 8 : for (i=0; i < count; i++) {
5019 :
5020 0 : const char *processor_key;
5021 0 : struct policy_handle key_handle;
5022 :
5023 4 : processor_key = talloc_asprintf(tctx, "%s\\%s\\Print Processors\\%s",
5024 : TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY,
5025 : environment,
5026 4 : info[i].info1.print_processor_name);
5027 :
5028 4 : torture_assert(tctx,
5029 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle, processor_key, &key_handle), "");
5030 :
5031 : /* nothing to check in there so far */
5032 :
5033 4 : torture_assert(tctx,
5034 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
5035 : }
5036 :
5037 4 : torture_comment(tctx, "Print Processor Info and winreg consistency test succeeded\n\n");
5038 :
5039 4 : return true;
5040 : }
5041 :
5042 : static bool test_GetPrinterDriver2_level(struct torture_context *tctx,
5043 : struct dcerpc_binding_handle *b,
5044 : struct policy_handle *handle,
5045 : const char *driver_name,
5046 : const char *architecture,
5047 : uint32_t level,
5048 : uint32_t client_major_version,
5049 : uint32_t client_minor_version,
5050 : union spoolss_DriverInfo *info_p,
5051 : WERROR *result);
5052 :
5053 0 : static const char *strip_path(const char *path)
5054 : {
5055 0 : char *p;
5056 :
5057 0 : if (path == NULL) {
5058 0 : return NULL;
5059 : }
5060 :
5061 0 : p = strrchr(path, '\\');
5062 0 : if (p) {
5063 0 : return p+1;
5064 : }
5065 :
5066 0 : return path;
5067 : }
5068 :
5069 0 : static const char **strip_paths(const char **path_array)
5070 : {
5071 0 : int i;
5072 :
5073 0 : if (path_array == NULL) {
5074 0 : return NULL;
5075 : }
5076 :
5077 0 : for (i=0; path_array[i] != NULL; i++) {
5078 0 : path_array[i] = strip_path(path_array[i]);
5079 : }
5080 :
5081 0 : return path_array;
5082 : }
5083 :
5084 0 : static const char *driver_winreg_date(TALLOC_CTX *mem_ctx, NTTIME nt)
5085 : {
5086 0 : time_t t;
5087 0 : struct tm *tm;
5088 :
5089 0 : if (nt == 0) {
5090 0 : return talloc_strdup(mem_ctx, "01/01/1601");
5091 : }
5092 :
5093 0 : t = nt_time_to_unix(nt);
5094 0 : tm = localtime(&t);
5095 :
5096 0 : return talloc_asprintf(mem_ctx, "%02d/%02d/%04d",
5097 0 : tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
5098 : }
5099 :
5100 0 : static const char *driver_winreg_version(TALLOC_CTX *mem_ctx, uint64_t v)
5101 : {
5102 0 : return talloc_asprintf(mem_ctx, "%u.%u.%u.%u",
5103 0 : (unsigned)((v >> 48) & 0xFFFF),
5104 0 : (unsigned)((v >> 32) & 0xFFFF),
5105 0 : (unsigned)((v >> 16) & 0xFFFF),
5106 : (unsigned)(v & 0xFFFF));
5107 : }
5108 :
5109 0 : static bool test_GetDriverInfo_winreg(struct torture_context *tctx,
5110 : struct dcerpc_binding_handle *b,
5111 : struct policy_handle *handle,
5112 : const char *printer_name,
5113 : const char *driver_name,
5114 : const char *environment,
5115 : enum spoolss_DriverOSVersion version,
5116 : struct dcerpc_binding_handle *winreg_handle,
5117 : struct policy_handle *hive_handle,
5118 : const char *server_name_slash)
5119 : {
5120 0 : WERROR result = WERR_OK;
5121 0 : union spoolss_DriverInfo info;
5122 0 : const char *driver_key;
5123 0 : struct policy_handle key_handle;
5124 :
5125 0 : const char *driver_path;
5126 0 : const char *data_file;
5127 0 : const char *config_file;
5128 0 : const char *help_file;
5129 0 : const char **dependent_files;
5130 :
5131 0 : const char *driver_date;
5132 0 : const char *inbox_driver_date;
5133 :
5134 0 : const char *driver_version;
5135 0 : const char *inbox_driver_version;
5136 :
5137 0 : ZERO_STRUCT(key_handle);
5138 :
5139 0 : torture_comment(tctx, "Testing Driver Info and winreg consistency\n");
5140 :
5141 0 : driver_key = talloc_asprintf(tctx, "%s\\%s\\Drivers\\Version-%d\\%s",
5142 : TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY,
5143 : environment,
5144 : version,
5145 : driver_name);
5146 :
5147 0 : torture_assert(tctx,
5148 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle, driver_key, &key_handle),
5149 : "failed to open driver key");
5150 :
5151 0 : if (torture_setting_bool(tctx, "samba3", false) ||
5152 0 : torture_setting_bool(tctx, "w2k3", false)) {
5153 0 : goto try_level6;
5154 : }
5155 :
5156 0 : if (handle) {
5157 0 : torture_assert(tctx,
5158 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, environment, 8, version, 0, &info, &result),
5159 : "failed to get driver info level 8");
5160 : } else {
5161 0 : torture_assert(tctx,
5162 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, environment, 8, driver_name, &info),
5163 : "failed to get driver info level 8");
5164 : }
5165 :
5166 0 : if (W_ERROR_EQUAL(result, WERR_INVALID_LEVEL)) {
5167 0 : goto try_level6;
5168 : }
5169 :
5170 0 : driver_path = strip_path(info.info8.driver_path);
5171 0 : data_file = strip_path(info.info8.data_file);
5172 0 : config_file = strip_path(info.info8.config_file);
5173 0 : help_file = strip_path(info.info8.help_file);
5174 0 : dependent_files = strip_paths(info.info8.dependent_files);
5175 :
5176 0 : driver_date = driver_winreg_date(tctx, info.info8.driver_date);
5177 0 : inbox_driver_date = driver_winreg_date(tctx, info.info8.min_inbox_driver_ver_date);
5178 :
5179 0 : driver_version = driver_winreg_version(tctx, info.info8.driver_version);
5180 0 : inbox_driver_version = driver_winreg_version(tctx, info.info8.min_inbox_driver_ver_version);
5181 :
5182 0 : test_sz("Configuration File", config_file);
5183 0 : test_sz("Data File", data_file);
5184 0 : test_sz("Datatype", info.info8.default_datatype);
5185 0 : test_sz("Driver", driver_path);
5186 0 : test_sz("DriverDate", driver_date);
5187 0 : test_sz("DriverVersion", driver_version);
5188 0 : test_sz("HardwareID", info.info8.hardware_id);
5189 0 : test_sz("Help File", help_file);
5190 0 : test_sz("InfPath", info.info8.inf_path);
5191 0 : test_sz("Manufacturer", info.info8.manufacturer_name);
5192 0 : test_sz("MinInboxDriverVerDate", inbox_driver_date);
5193 0 : test_sz("MinInboxDriverVerVersion", inbox_driver_version);
5194 0 : test_sz("Monitor", info.info8.monitor_name);
5195 0 : test_sz("OEM URL", info.info8.manufacturer_url);
5196 0 : test_sz("Print Processor", info.info8.print_processor);
5197 0 : test_sz("Provider", info.info8.provider);
5198 0 : test_sz("VendorSetup", info.info8.vendor_setup);
5199 0 : test_multi_sz("ColorProfiles", info.info8.color_profiles);
5200 0 : test_multi_sz("Dependent Files", dependent_files);
5201 0 : test_multi_sz("CoreDependencies", info.info8.core_driver_dependencies);
5202 0 : test_multi_sz("Previous Names", info.info8.previous_names);
5203 : /* test_dword("Attributes", ?); */
5204 0 : test_dword("PrinterDriverAttributes", info.info8.printer_driver_attributes);
5205 0 : test_dword("Version", info.info8.version);
5206 : /* test_dword("TempDir", ?); */
5207 :
5208 0 : try_level6:
5209 :
5210 0 : if (handle) {
5211 0 : torture_assert(tctx,
5212 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, environment, 6, version, 0, &info, &result),
5213 : "failed to get driver info level 6");
5214 : } else {
5215 0 : torture_assert(tctx,
5216 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, environment, 6, driver_name, &info),
5217 : "failed to get driver info level 6");
5218 : }
5219 :
5220 0 : driver_path = strip_path(info.info6.driver_path);
5221 0 : data_file = strip_path(info.info6.data_file);
5222 0 : config_file = strip_path(info.info6.config_file);
5223 0 : help_file = strip_path(info.info6.help_file);
5224 0 : dependent_files = strip_paths(info.info6.dependent_files);
5225 :
5226 0 : driver_date = driver_winreg_date(tctx, info.info6.driver_date);
5227 :
5228 0 : driver_version = driver_winreg_version(tctx, info.info6.driver_version);
5229 :
5230 0 : test_sz("Configuration File", config_file);
5231 0 : test_sz("Data File", data_file);
5232 0 : test_sz("Datatype", info.info6.default_datatype);
5233 0 : test_sz("Driver", driver_path);
5234 0 : if (torture_setting_bool(tctx, "w2k3", false)) {
5235 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 8);
5236 0 : push_nttime(blob.data, 0, info.info6.driver_date);
5237 0 : test_binary("DriverDate", blob);
5238 0 : SBVAL(blob.data, 0, info.info6.driver_version);
5239 0 : test_binary("DriverVersion", blob);
5240 : } else {
5241 0 : test_sz("DriverDate", driver_date);
5242 0 : test_sz("DriverVersion", driver_version);
5243 : }
5244 0 : test_sz("HardwareID", info.info6.hardware_id);
5245 0 : test_sz("Help File", help_file);
5246 0 : test_sz("Manufacturer", info.info6.manufacturer_name);
5247 0 : test_sz("Monitor", info.info6.monitor_name);
5248 0 : test_sz("OEM URL", info.info6.manufacturer_url);
5249 0 : test_sz("Provider", info.info6.provider);
5250 0 : test_multi_sz("Dependent Files", dependent_files);
5251 0 : test_multi_sz("Previous Names", info.info6.previous_names);
5252 : /* test_dword("Attributes", ?); */
5253 0 : test_dword("Version", info.info6.version);
5254 : /* test_dword("TempDir", ?); */
5255 :
5256 0 : if (handle) {
5257 0 : torture_assert(tctx,
5258 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, environment, 3, version, 0, &info, &result),
5259 : "failed to get driver info level 3");
5260 : } else {
5261 0 : torture_assert(tctx,
5262 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, environment, 3, driver_name, &info),
5263 : "failed to get driver info level 3");
5264 : }
5265 :
5266 0 : driver_path = strip_path(info.info3.driver_path);
5267 0 : data_file = strip_path(info.info3.data_file);
5268 0 : config_file = strip_path(info.info3.config_file);
5269 0 : help_file = strip_path(info.info3.help_file);
5270 0 : dependent_files = strip_paths(info.info3.dependent_files);
5271 :
5272 0 : test_sz("Configuration File", config_file);
5273 0 : test_sz("Data File", data_file);
5274 0 : test_sz("Datatype", info.info3.default_datatype);
5275 0 : test_sz("Driver", driver_path);
5276 0 : test_sz("Help File", help_file);
5277 0 : test_sz("Monitor", info.info3.monitor_name);
5278 0 : test_multi_sz("Dependent Files", dependent_files);
5279 : /* test_dword("Attributes", ?); */
5280 0 : test_dword("Version", info.info3.version);
5281 : /* test_dword("TempDir", ?); */
5282 :
5283 :
5284 0 : torture_assert(tctx,
5285 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
5286 :
5287 0 : torture_comment(tctx, "Driver Info and winreg consistency test succeeded\n\n");
5288 :
5289 0 : return true;
5290 : }
5291 :
5292 : #undef test_sz
5293 : #undef test_dword
5294 :
5295 168 : static bool test_SetPrinterData(struct torture_context *tctx,
5296 : struct dcerpc_binding_handle *b,
5297 : struct policy_handle *handle,
5298 : const char *value_name,
5299 : enum winreg_Type type,
5300 : uint8_t *data,
5301 : uint32_t offered)
5302 : {
5303 0 : struct spoolss_SetPrinterData r;
5304 :
5305 168 : r.in.handle = handle;
5306 168 : r.in.value_name = value_name;
5307 168 : r.in.type = type;
5308 168 : r.in.data = data;
5309 168 : r.in.offered = offered;
5310 :
5311 168 : torture_comment(tctx, "Testing SetPrinterData(%s)\n",
5312 : r.in.value_name);
5313 :
5314 168 : torture_assert_ntstatus_ok(tctx,
5315 : dcerpc_spoolss_SetPrinterData_r(b, tctx, &r),
5316 : "SetPrinterData failed");
5317 168 : torture_assert_werr_ok(tctx, r.out.result,
5318 : "SetPrinterData failed");
5319 :
5320 168 : return true;
5321 : }
5322 :
5323 28 : static bool test_SetPrinterData_matrix(struct torture_context *tctx,
5324 : struct dcerpc_binding_handle *b,
5325 : struct policy_handle *handle,
5326 : const char *printer_name,
5327 : struct dcerpc_binding_handle *winreg_handle,
5328 : struct policy_handle *hive_handle)
5329 : {
5330 28 : const char *values[] = {
5331 : "spootyfoot",
5332 : "spooty\\foot",
5333 : #if 0
5334 : /* FIXME: not working with s3 atm. */
5335 : "spooty,foot",
5336 : "spooty,fo,ot",
5337 : #endif
5338 : "spooty foot",
5339 : #if 0
5340 : /* FIXME: not working with s3 atm. */
5341 : "spooty\\fo,ot",
5342 : "spooty,fo\\ot"
5343 : #endif
5344 : };
5345 0 : int i;
5346 :
5347 112 : for (i=0; i < ARRAY_SIZE(values); i++) {
5348 :
5349 84 : enum winreg_Type type, expected_type = REG_SZ;
5350 0 : DATA_BLOB blob;
5351 0 : uint8_t *data;
5352 0 : uint32_t needed;
5353 :
5354 84 : torture_assert(tctx, push_reg_sz(tctx, &blob, "dog"), "");
5355 84 : type = REG_SZ;
5356 :
5357 84 : torture_assert(tctx,
5358 : test_SetPrinterData(tctx, b, handle, values[i], REG_SZ, blob.data, blob.length),
5359 : "SetPrinterData failed");
5360 :
5361 84 : torture_assert(tctx,
5362 : test_GetPrinterData_checktype(tctx, b, handle, values[i], &expected_type, &type, &data, &needed),
5363 : "GetPrinterData failed");
5364 :
5365 84 : torture_assert_int_equal(tctx, type, REG_SZ, "type mismatch");
5366 84 : torture_assert_int_equal(tctx, needed, blob.length, "size mismatch");
5367 84 : torture_assert_mem_equal(tctx, data, blob.data, blob.length, "buffer mismatch");
5368 :
5369 84 : if (winreg_handle && hive_handle) {
5370 :
5371 0 : enum winreg_Type w_type;
5372 0 : uint32_t w_size;
5373 0 : uint32_t w_length;
5374 0 : uint8_t *w_data;
5375 :
5376 24 : torture_assert(tctx,
5377 : test_winreg_query_printerdata(tctx, winreg_handle, hive_handle,
5378 : printer_name, "PrinterDriverData", values[i],
5379 : &w_type, &w_size, &w_length, &w_data), "");
5380 :
5381 24 : torture_assert_int_equal(tctx, w_type, REG_SZ, "winreg type mismatch");
5382 24 : torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
5383 24 : torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
5384 24 : torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
5385 : }
5386 :
5387 84 : torture_assert(tctx,
5388 : test_DeletePrinterData(tctx, b, handle, values[i]),
5389 : "DeletePrinterData failed");
5390 : }
5391 :
5392 28 : return true;
5393 : }
5394 :
5395 :
5396 : static bool test_EnumPrinterKey(struct torture_context *tctx,
5397 : struct dcerpc_binding_handle *b,
5398 : struct policy_handle *handle,
5399 : const char *key_name,
5400 : const char ***array);
5401 :
5402 1200 : static bool test_SetPrinterDataEx(struct torture_context *tctx,
5403 : struct dcerpc_binding_handle *b,
5404 : struct policy_handle *handle,
5405 : const char *key_name,
5406 : const char *value_name,
5407 : enum winreg_Type type,
5408 : uint8_t *data,
5409 : uint32_t offered)
5410 : {
5411 0 : NTSTATUS status;
5412 0 : struct spoolss_SetPrinterDataEx r;
5413 :
5414 1200 : r.in.handle = handle;
5415 1200 : r.in.key_name = key_name;
5416 1200 : r.in.value_name = value_name;
5417 1200 : r.in.type = type;
5418 1200 : r.in.data = data;
5419 1200 : r.in.offered = offered;
5420 :
5421 1200 : torture_comment(tctx, "Testing SetPrinterDataEx(%s - %s) type: %s, offered: 0x%08x\n",
5422 1200 : r.in.key_name, r.in.value_name, str_regtype(r.in.type), r.in.offered);
5423 :
5424 1200 : status = dcerpc_spoolss_SetPrinterDataEx_r(b, tctx, &r);
5425 :
5426 1200 : torture_assert_ntstatus_ok(tctx, status, "SetPrinterDataEx failed");
5427 1200 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinterDataEx failed");
5428 :
5429 1200 : return true;
5430 : }
5431 :
5432 8 : static bool test_SetPrinterDataEx_keys(struct torture_context *tctx,
5433 : struct dcerpc_pipe *p,
5434 : struct policy_handle *handle)
5435 : {
5436 8 : struct dcerpc_binding_handle *b = p->binding_handle;
5437 8 : const char *value_name = "dog";
5438 8 : const char *keys[] = {
5439 : "torturedataex",
5440 : "torture data ex",
5441 : "torturedataex_with_subkey\\subkey",
5442 : "torturedataex_with_subkey\\subkey:0",
5443 : "torturedataex_with_subkey\\subkey:1",
5444 : "torturedataex_with_subkey\\subkey\\subsubkey",
5445 : "torturedataex_with_subkey\\subkey\\subsubkey:0",
5446 : "torturedataex_with_subkey\\subkey\\subsubkey:1",
5447 : "torture,data",
5448 : "torture,data,ex",
5449 : "torture,data\\ex",
5450 : "torture\\data,ex",
5451 : "torture/data",
5452 : "torture/data ex",
5453 : "torture/data ex/sub",
5454 : "torture//data",
5455 : "torture//data ex",
5456 : "torture//data ex/sub",
5457 : "torture//data ex//sub",
5458 : };
5459 0 : int i;
5460 :
5461 160 : for (i=0; i < ARRAY_SIZE(keys); i++) {
5462 :
5463 0 : char *c;
5464 0 : const char *key;
5465 0 : enum winreg_Type type;
5466 0 : DATA_BLOB blob_in, blob_out;
5467 0 : const char **subkeys;
5468 0 : uint32_t ecount;
5469 0 : struct spoolss_PrinterEnumValues *einfo;
5470 0 : uint32_t needed;
5471 :
5472 152 : blob_in = data_blob_talloc(tctx, NULL, 42);
5473 :
5474 152 : generate_random_buffer(blob_in.data, blob_in.length);
5475 :
5476 152 : torture_assert(tctx,
5477 : test_SetPrinterDataEx(tctx, b, handle, keys[i], value_name, REG_BINARY, blob_in.data, blob_in.length),
5478 : "failed to call SetPrinterDataEx");
5479 :
5480 152 : torture_assert(tctx,
5481 : test_GetPrinterDataEx(tctx, p, handle, keys[i], value_name, &type, &blob_out.data, &needed),
5482 : "failed to call GetPrinterDataEx");
5483 :
5484 152 : blob_out.length = needed;
5485 152 : torture_assert(tctx,
5486 : test_EnumPrinterDataEx(tctx, b, handle, keys[i], &ecount, &einfo),
5487 : "failed to call EnumPrinterDataEx");
5488 :
5489 152 : torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
5490 152 : torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
5491 152 : torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
5492 :
5493 152 : torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5494 152 : torture_assert_str_equal(tctx, einfo[0].value_name, value_name, "value_name mismatch");
5495 152 : torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(value_name)*2, "unexpected value_name_len");
5496 152 : torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
5497 152 : torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
5498 152 : if (einfo[0].data_length > 0) {
5499 152 : torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
5500 : }
5501 :
5502 152 : key = talloc_strdup(tctx, keys[i]);
5503 :
5504 152 : if (!test_DeletePrinterDataEx(tctx, b, handle, keys[i], value_name)) {
5505 0 : return false;
5506 : }
5507 :
5508 152 : c = strchr(key, '\\');
5509 152 : if (c) {
5510 0 : int k;
5511 :
5512 : /* we have subkeys */
5513 :
5514 64 : *c = 0;
5515 :
5516 64 : if (!test_EnumPrinterKey(tctx, b, handle, key, &subkeys)) {
5517 0 : return false;
5518 : }
5519 :
5520 128 : for (k=0; subkeys && subkeys[k]; k++) {
5521 :
5522 64 : const char *current_key = talloc_asprintf(tctx, "%s\\%s", key, subkeys[k]);
5523 :
5524 64 : if (!test_DeletePrinterKey(tctx, b, handle, current_key)) {
5525 0 : return false;
5526 : }
5527 : }
5528 :
5529 64 : if (!test_DeletePrinterKey(tctx, b, handle, key)) {
5530 0 : return false;
5531 : }
5532 :
5533 : } else {
5534 88 : if (!test_DeletePrinterKey(tctx, b, handle, key)) {
5535 0 : return false;
5536 : }
5537 : }
5538 : }
5539 :
5540 8 : return true;
5541 : }
5542 :
5543 8 : static bool test_SetPrinterDataEx_values(struct torture_context *tctx,
5544 : struct dcerpc_pipe *p,
5545 : struct policy_handle *handle)
5546 : {
5547 8 : struct dcerpc_binding_handle *b = p->binding_handle;
5548 8 : const char *key = "torturedataex";
5549 8 : const char *values[] = {
5550 : "torture_value",
5551 : "torture value",
5552 : "torture,value",
5553 : "torture/value",
5554 : "torture\\value",
5555 : "torture\\\\value"
5556 : };
5557 0 : int i;
5558 :
5559 56 : for (i=0; i < ARRAY_SIZE(values); i++) {
5560 :
5561 48 : enum winreg_Type type = REG_NONE;
5562 48 : DATA_BLOB blob_in = data_blob_null;
5563 48 : DATA_BLOB blob_out = data_blob_null;
5564 0 : uint32_t ecount;
5565 0 : struct spoolss_PrinterEnumValues *einfo;
5566 48 : uint32_t needed = 0;
5567 :
5568 48 : if (torture_setting_bool(tctx, "samba3", false)) {
5569 0 : char *q;
5570 48 : q = strrchr(values[i], ',');
5571 48 : if (q) {
5572 8 : torture_comment(tctx, "skipping valuename '%s' including ',' character against Samba3\n",
5573 : values[i]);
5574 8 : continue;
5575 : }
5576 : }
5577 :
5578 40 : blob_in = data_blob_talloc(tctx, NULL, 42);
5579 :
5580 40 : generate_random_buffer(blob_in.data, blob_in.length);
5581 :
5582 40 : torture_assert(tctx,
5583 : test_SetPrinterDataEx(tctx, b, handle, key, values[i], REG_BINARY, blob_in.data, blob_in.length),
5584 : "failed to call SetPrinterDataEx");
5585 :
5586 40 : torture_assert(tctx,
5587 : test_GetPrinterDataEx(tctx, p, handle, key, values[i], &type, &blob_out.data, &needed),
5588 : "failed to call GetPrinterDataEx");
5589 :
5590 40 : blob_out.length = needed;
5591 40 : torture_assert(tctx,
5592 : test_EnumPrinterDataEx(tctx, b, handle, key, &ecount, &einfo),
5593 : "failed to call EnumPrinterDataEx");
5594 :
5595 40 : torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
5596 40 : torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
5597 40 : torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
5598 :
5599 40 : torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5600 40 : torture_assert_str_equal(tctx, einfo[0].value_name, values[i], "value_name mismatch");
5601 40 : torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(values[i])*2, "unexpected value_name_len");
5602 40 : torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
5603 40 : torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
5604 40 : if (einfo[0].data_length > 0) {
5605 40 : torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
5606 : }
5607 :
5608 40 : torture_assert(tctx,
5609 : test_DeletePrinterDataEx(tctx, b, handle, key, values[i]),
5610 : "failed to call DeletePrinterDataEx");
5611 : }
5612 :
5613 8 : return true;
5614 : }
5615 :
5616 :
5617 36 : static bool test_SetPrinterDataEx_matrix(struct torture_context *tctx,
5618 : struct dcerpc_pipe *p,
5619 : struct policy_handle *handle,
5620 : const char *printername,
5621 : struct dcerpc_binding_handle *winreg_handle,
5622 : struct policy_handle *hive_handle)
5623 : {
5624 36 : struct dcerpc_binding_handle *b = p->binding_handle;
5625 36 : const char *value_name = "dog";
5626 36 : const char *key_name = "torturedataex";
5627 36 : enum winreg_Type types[] = {
5628 : REG_SZ,
5629 : REG_MULTI_SZ,
5630 : REG_DWORD,
5631 : REG_BINARY
5632 : };
5633 36 : const char *str = "abcdefghi";
5634 0 : size_t t, s;
5635 :
5636 180 : for (t=0; t < ARRAY_SIZE(types); t++) {
5637 1152 : for (s=0; s < strlen(str); s++) {
5638 :
5639 0 : enum winreg_Type type;
5640 1008 : const char *string = talloc_strndup(tctx, str, s);
5641 0 : const char *array[2];
5642 1008 : DATA_BLOB blob = data_blob_string_const(string);
5643 0 : DATA_BLOB data;
5644 0 : uint8_t *data_out;
5645 1008 : uint32_t needed, offered = 0;
5646 0 : uint32_t ecount;
5647 0 : struct spoolss_PrinterEnumValues *einfo;
5648 :
5649 1008 : array[0] = talloc_strdup(tctx, string);
5650 1008 : array[1] = NULL;
5651 :
5652 1008 : if (types[t] == REG_DWORD) {
5653 36 : s = 0xffff;
5654 : }
5655 :
5656 1008 : switch (types[t]) {
5657 324 : case REG_BINARY:
5658 324 : data = blob;
5659 324 : offered = blob.length;
5660 324 : break;
5661 36 : case REG_DWORD:
5662 36 : data = data_blob_talloc(tctx, NULL, 4);
5663 36 : SIVAL(data.data, 0, 0x12345678);
5664 36 : offered = 4;
5665 36 : break;
5666 324 : case REG_SZ:
5667 324 : torture_assert(tctx, push_reg_sz(tctx, &data, string), "");
5668 324 : type = REG_SZ;
5669 324 : offered = data.length;
5670 : /*strlen_m_term(data.string)*2;*/
5671 324 : break;
5672 324 : case REG_MULTI_SZ:
5673 324 : torture_assert(tctx, push_reg_multi_sz(tctx, &data, array), "");
5674 324 : type = REG_MULTI_SZ;
5675 324 : offered = data.length;
5676 324 : break;
5677 0 : default:
5678 0 : torture_fail(tctx, talloc_asprintf(tctx, "type %d untested\n", types[t]));
5679 : }
5680 :
5681 1008 : torture_assert(tctx,
5682 : test_SetPrinterDataEx(tctx, b, handle, key_name, value_name, types[t], data.data, offered),
5683 : "failed to call SetPrinterDataEx");
5684 :
5685 1008 : torture_assert(tctx,
5686 : test_GetPrinterDataEx_checktype(tctx, p, handle, key_name, value_name, &types[t], &type, &data_out, &needed),
5687 : "failed to call GetPrinterDataEx");
5688 :
5689 1008 : torture_assert(tctx,
5690 : test_EnumPrinterDataEx(tctx, b, handle, key_name, &ecount, &einfo),
5691 : "failed to call EnumPrinterDataEx");
5692 :
5693 1008 : torture_assert_int_equal(tctx, types[t], type, "type mismatch");
5694 1008 : torture_assert_int_equal(tctx, needed, offered, "size mismatch");
5695 1008 : torture_assert_mem_equal(tctx, data_out, data.data, offered, "buffer mismatch");
5696 :
5697 1008 : torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5698 1008 : torture_assert_str_equal(tctx, einfo[0].value_name, value_name, "value_name mismatch");
5699 1008 : torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(value_name)*2, "unexpected value_name_len");
5700 1008 : torture_assert_int_equal(tctx, einfo[0].type, types[t], "type mismatch");
5701 1008 : torture_assert_int_equal(tctx, einfo[0].data_length, offered, "size mismatch");
5702 1008 : if (einfo[0].data_length > 0) {
5703 972 : torture_assert_mem_equal(tctx, einfo[0].data->data, data.data, offered, "buffer mismatch");
5704 : }
5705 :
5706 1008 : if (winreg_handle && hive_handle) {
5707 0 : enum winreg_Type w_type;
5708 0 : uint32_t w_size;
5709 0 : uint32_t w_length;
5710 0 : uint8_t *w_data;
5711 :
5712 224 : torture_assert(tctx,
5713 : test_winreg_query_printerdata(tctx, winreg_handle, hive_handle,
5714 : printername, key_name, value_name,
5715 : &w_type, &w_size, &w_length, &w_data), "");
5716 :
5717 224 : torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
5718 224 : torture_assert_int_equal(tctx, w_size, offered, "winreg size mismatch");
5719 224 : torture_assert_int_equal(tctx, w_length, offered, "winreg length mismatch");
5720 224 : torture_assert_mem_equal(tctx, w_data, data.data, offered, "winreg buffer mismatch");
5721 : }
5722 :
5723 1008 : torture_assert(tctx,
5724 : test_DeletePrinterDataEx(tctx, b, handle, key_name, value_name),
5725 : "failed to call DeletePrinterDataEx");
5726 : }
5727 : }
5728 :
5729 36 : return true;
5730 : }
5731 :
5732 8 : static bool test_PrinterData_winreg(struct torture_context *tctx,
5733 : struct dcerpc_pipe *p,
5734 : struct policy_handle *handle,
5735 : const char *printer_name)
5736 : {
5737 8 : struct dcerpc_binding_handle *b = p->binding_handle;
5738 0 : struct dcerpc_pipe *p2;
5739 8 : bool ret = true;
5740 0 : struct policy_handle hive_handle;
5741 0 : struct dcerpc_binding_handle *b2;
5742 :
5743 8 : torture_assert_ntstatus_ok(tctx,
5744 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5745 : "could not open winreg pipe");
5746 8 : b2 = p2->binding_handle;
5747 :
5748 8 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5749 :
5750 8 : ret &= test_SetPrinterData_matrix(tctx, b, handle, printer_name, b2, &hive_handle);
5751 8 : ret &= test_SetPrinterDataEx_matrix(tctx, p, handle, printer_name, b2, &hive_handle);
5752 :
5753 8 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5754 :
5755 8 : talloc_free(p2);
5756 :
5757 8 : return ret;
5758 : }
5759 :
5760 24 : static bool test_Forms_winreg(struct torture_context *tctx,
5761 : struct dcerpc_binding_handle *b,
5762 : struct policy_handle *handle,
5763 : bool print_server,
5764 : const char *printer_name)
5765 : {
5766 0 : struct dcerpc_pipe *p2;
5767 24 : bool ret = true;
5768 0 : struct policy_handle hive_handle;
5769 0 : struct dcerpc_binding_handle *b2;
5770 :
5771 24 : torture_assert_ntstatus_ok(tctx,
5772 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5773 : "could not open winreg pipe");
5774 24 : b2 = p2->binding_handle;
5775 :
5776 24 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5777 :
5778 24 : ret = test_Forms(tctx, b, handle, print_server, printer_name, b2, &hive_handle);
5779 :
5780 24 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5781 :
5782 24 : talloc_free(p2);
5783 :
5784 24 : return ret;
5785 : }
5786 :
5787 8 : static bool test_PrinterInfo_winreg(struct torture_context *tctx,
5788 : struct dcerpc_pipe *p,
5789 : struct policy_handle *handle,
5790 : const char *printer_name)
5791 : {
5792 8 : struct dcerpc_binding_handle *b = p->binding_handle;
5793 0 : struct dcerpc_pipe *p2;
5794 8 : bool ret = true;
5795 0 : struct policy_handle hive_handle;
5796 0 : struct dcerpc_binding_handle *b2;
5797 :
5798 8 : torture_assert_ntstatus_ok(tctx,
5799 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5800 : "could not open winreg pipe");
5801 8 : b2 = p2->binding_handle;
5802 :
5803 8 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5804 :
5805 8 : ret = test_GetPrinterInfo_winreg(tctx, b, handle, printer_name, b2, &hive_handle);
5806 :
5807 8 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5808 :
5809 8 : talloc_free(p2);
5810 :
5811 8 : return ret;
5812 : }
5813 :
5814 4 : static bool test_PrintserverInfo_winreg(struct torture_context *tctx,
5815 : struct dcerpc_pipe *p,
5816 : struct policy_handle *handle)
5817 : {
5818 4 : struct dcerpc_binding_handle *b = p->binding_handle;
5819 0 : struct dcerpc_pipe *p2;
5820 4 : bool ret = true;
5821 0 : struct policy_handle hive_handle;
5822 0 : struct dcerpc_binding_handle *b2;
5823 :
5824 4 : torture_assert_ntstatus_ok(tctx,
5825 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5826 : "could not open winreg pipe");
5827 4 : b2 = p2->binding_handle;
5828 :
5829 4 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5830 :
5831 4 : ret = test_GetPrintserverInfo_winreg(tctx, b, handle, b2, &hive_handle);
5832 :
5833 4 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5834 :
5835 4 : talloc_free(p2);
5836 :
5837 4 : return ret;
5838 : }
5839 :
5840 :
5841 0 : static bool test_DriverInfo_winreg(struct torture_context *tctx,
5842 : struct dcerpc_pipe *p,
5843 : struct policy_handle *handle,
5844 : const char *printer_name,
5845 : const char *driver_name,
5846 : const char *environment,
5847 : enum spoolss_DriverOSVersion version)
5848 : {
5849 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5850 0 : struct dcerpc_pipe *p2;
5851 0 : bool ret = true;
5852 0 : struct policy_handle hive_handle;
5853 0 : struct dcerpc_binding_handle *b2;
5854 :
5855 0 : torture_assert_ntstatus_ok(tctx,
5856 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5857 : "could not open winreg pipe");
5858 0 : b2 = p2->binding_handle;
5859 :
5860 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5861 :
5862 0 : ret = test_GetDriverInfo_winreg(tctx, b, handle, printer_name, driver_name, environment, version, b2, &hive_handle, NULL);
5863 :
5864 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5865 :
5866 0 : talloc_free(p2);
5867 :
5868 0 : return ret;
5869 : }
5870 :
5871 4 : static bool test_PrintProcessors_winreg(struct torture_context *tctx,
5872 : struct dcerpc_binding_handle *b,
5873 : const char *environment)
5874 : {
5875 0 : struct dcerpc_pipe *p2;
5876 4 : bool ret = true;
5877 0 : struct policy_handle hive_handle;
5878 0 : struct dcerpc_binding_handle *b2;
5879 :
5880 4 : torture_assert_ntstatus_ok(tctx,
5881 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5882 : "could not open winreg pipe");
5883 4 : b2 = p2->binding_handle;
5884 :
5885 4 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5886 :
5887 4 : ret = test_PrintProcessors(tctx, b, environment, b2, &hive_handle);
5888 :
5889 4 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5890 :
5891 4 : talloc_free(p2);
5892 :
5893 4 : return ret;
5894 : }
5895 :
5896 8 : static bool test_PrinterData_DsSpooler(struct torture_context *tctx,
5897 : struct dcerpc_pipe *p,
5898 : struct policy_handle *handle,
5899 : const char *printer_name)
5900 : {
5901 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
5902 0 : struct spoolss_DevmodeContainer devmode_ctr;
5903 0 : struct sec_desc_buf secdesc_ctr;
5904 0 : union spoolss_SetPrinterInfo sinfo;
5905 0 : union spoolss_PrinterInfo info;
5906 8 : struct dcerpc_binding_handle *b = p->binding_handle;
5907 0 : const char *pname;
5908 :
5909 8 : ZERO_STRUCT(info_ctr);
5910 8 : ZERO_STRUCT(devmode_ctr);
5911 8 : ZERO_STRUCT(secdesc_ctr);
5912 :
5913 8 : torture_comment(tctx, "Testing DsSpooler <-> SetPrinter relations\n");
5914 :
5915 8 : torture_assert(tctx,
5916 : test_GetPrinter_level(tctx, b, handle, 2, &info),
5917 : "failed to query Printer level 2");
5918 :
5919 8 : torture_assert(tctx,
5920 : PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo),
5921 : "failed to convert");
5922 :
5923 8 : info_ctr.level = 2;
5924 8 : info_ctr.info = sinfo;
5925 :
5926 : #define TEST_SZ(wname, iname) \
5927 : do {\
5928 : enum winreg_Type type;\
5929 : uint8_t *data;\
5930 : uint32_t needed;\
5931 : DATA_BLOB blob;\
5932 : const char *str;\
5933 : torture_assert(tctx,\
5934 : test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5935 : "failed to query");\
5936 : torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5937 : blob = data_blob_const(data, needed);\
5938 : torture_assert(tctx,\
5939 : pull_reg_sz(tctx, &blob, &str),\
5940 : "failed to pull REG_SZ");\
5941 : torture_assert_str_equal(tctx, str, iname, "unexpected result");\
5942 : } while(0);
5943 :
5944 :
5945 : #define TEST_SET_SZ(wname, iname, val) \
5946 : do {\
5947 : enum winreg_Type type;\
5948 : uint8_t *data;\
5949 : uint32_t needed;\
5950 : DATA_BLOB blob;\
5951 : const char *str;\
5952 : sinfo.info2->iname = val;\
5953 : torture_assert(tctx,\
5954 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5955 : "failed to call SetPrinter");\
5956 : torture_assert(tctx,\
5957 : test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5958 : "failed to query");\
5959 : torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5960 : blob = data_blob_const(data, needed);\
5961 : torture_assert(tctx,\
5962 : pull_reg_sz(tctx, &blob, &str),\
5963 : "failed to pull REG_SZ");\
5964 : torture_assert_str_equal(tctx, str, val, "unexpected result");\
5965 : } while(0);
5966 :
5967 : #define TEST_SET_DWORD(wname, iname, val) \
5968 : do {\
5969 : enum winreg_Type type;\
5970 : uint8_t *data;\
5971 : uint32_t needed;\
5972 : uint32_t value;\
5973 : sinfo.info2->iname = val;\
5974 : torture_assert(tctx,\
5975 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5976 : "failed to call SetPrinter");\
5977 : torture_assert(tctx,\
5978 : test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5979 : "failed to query");\
5980 : torture_assert_int_equal(tctx, type, REG_DWORD, "unexpected type");\
5981 : torture_assert_int_equal(tctx, needed, 4, "unexpected length");\
5982 : value = IVAL(data, 0); \
5983 : torture_assert_int_equal(tctx, value, val, "unexpected result");\
5984 : } while(0);
5985 :
5986 8 : TEST_SET_SZ("description", comment, "newval");
5987 8 : TEST_SET_SZ("location", location, "newval");
5988 8 : TEST_SET_SZ("driverName", drivername, "newval");
5989 : /* TEST_SET_DWORD("priority", priority, 25); */
5990 :
5991 8 : torture_assert(tctx,
5992 : test_GetPrinter_level(tctx, b, handle, 2, &info),
5993 : "failed to query Printer level 2");
5994 :
5995 8 : TEST_SZ("description", info.info2.comment);
5996 8 : TEST_SZ("driverName", info.info2.drivername);
5997 8 : TEST_SZ("location", info.info2.location);
5998 :
5999 8 : pname = strrchr(info.info2.printername, '\\');
6000 8 : if (pname == NULL) {
6001 0 : pname = info.info2.printername;
6002 : } else {
6003 8 : pname++;
6004 : }
6005 8 : TEST_SZ("printerName", pname);
6006 : /* TEST_SZ("printSeparatorFile", info.info2.sepfile); */
6007 : /* TEST_SZ("printShareName", info.info2.sharename); */
6008 :
6009 : /* FIXME gd: complete the list */
6010 :
6011 : #undef TEST_SZ
6012 : #undef TEST_SET_SZ
6013 : #undef TEST_DWORD
6014 :
6015 8 : torture_comment(tctx, "DsSpooler <-> SetPrinter relations test succeeded\n\n");
6016 :
6017 8 : return true;
6018 : }
6019 :
6020 4 : static bool test_print_processors_winreg(struct torture_context *tctx,
6021 : void *private_data)
6022 : {
6023 0 : struct test_spoolss_context *ctx =
6024 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6025 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6026 4 : struct dcerpc_binding_handle *b = p->binding_handle;
6027 :
6028 4 : return test_PrintProcessors_winreg(tctx, b, ctx->environment);
6029 : }
6030 :
6031 4 : static bool test_AddPrintProcessor(struct torture_context *tctx,
6032 : struct dcerpc_binding_handle *b,
6033 : const char *environment,
6034 : const char *path_name,
6035 : const char *print_processor_name,
6036 : WERROR expected_error)
6037 : {
6038 0 : struct spoolss_AddPrintProcessor r;
6039 :
6040 4 : r.in.server = NULL;
6041 4 : r.in.architecture = environment;
6042 4 : r.in.path_name = path_name;
6043 4 : r.in.print_processor_name = print_processor_name;
6044 :
6045 4 : torture_comment(tctx, "Testing AddPrintProcessor(%s)\n",
6046 : print_processor_name);
6047 :
6048 4 : torture_assert_ntstatus_ok(tctx,
6049 : dcerpc_spoolss_AddPrintProcessor_r(b, tctx, &r),
6050 : "spoolss_AddPrintProcessor failed");
6051 4 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6052 : "spoolss_AddPrintProcessor failed");
6053 :
6054 0 : return true;
6055 : }
6056 :
6057 0 : static bool test_DeletePrintProcessor(struct torture_context *tctx,
6058 : struct dcerpc_binding_handle *b,
6059 : const char *environment,
6060 : const char *print_processor_name,
6061 : WERROR expected_error)
6062 : {
6063 0 : struct spoolss_DeletePrintProcessor r;
6064 :
6065 0 : r.in.server = NULL;
6066 0 : r.in.architecture = environment;
6067 0 : r.in.print_processor_name = print_processor_name;
6068 :
6069 0 : torture_comment(tctx, "Testing DeletePrintProcessor(%s)\n",
6070 : print_processor_name);
6071 :
6072 0 : torture_assert_ntstatus_ok(tctx,
6073 : dcerpc_spoolss_DeletePrintProcessor_r(b, tctx, &r),
6074 : "spoolss_DeletePrintProcessor failed");
6075 0 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6076 : "spoolss_DeletePrintProcessor failed");
6077 :
6078 0 : return true;
6079 : }
6080 :
6081 4 : static bool test_add_print_processor(struct torture_context *tctx,
6082 : void *private_data)
6083 : {
6084 0 : struct test_spoolss_context *ctx =
6085 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6086 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6087 4 : struct dcerpc_binding_handle *b = p->binding_handle;
6088 0 : int i;
6089 :
6090 0 : struct {
6091 : const char *environment;
6092 : const char *path_name;
6093 : const char *print_processor_name;
6094 : WERROR expected_add_result;
6095 : WERROR expected_del_result;
6096 4 : } tests[] = {
6097 : {
6098 4 : .environment = ctx->environment,
6099 : .path_name = "",
6100 : .print_processor_name = "winprint",
6101 : .expected_add_result = WERR_PRINT_PROCESSOR_ALREADY_INSTALLED,
6102 : .expected_del_result = WERR_CAN_NOT_COMPLETE
6103 : },{
6104 4 : .environment = ctx->environment,
6105 : .path_name = "",
6106 : .print_processor_name = "unknown",
6107 : .expected_add_result = WERR_MOD_NOT_FOUND,
6108 : .expected_del_result = WERR_UNKNOWN_PRINTPROCESSOR
6109 : }
6110 : };
6111 :
6112 4 : for (i=0; i < ARRAY_SIZE(tests); i++) {
6113 4 : torture_assert(tctx,
6114 : test_AddPrintProcessor(tctx, b,
6115 : tests[i].environment,
6116 : tests[i].path_name,
6117 : tests[i].print_processor_name,
6118 : tests[i].expected_add_result),
6119 : "add print processor failed");
6120 0 : torture_assert(tctx,
6121 : test_DeletePrintProcessor(tctx, b,
6122 : tests[i].environment,
6123 : tests[i].print_processor_name,
6124 : tests[i].expected_del_result),
6125 : "delete print processor failed");
6126 : }
6127 :
6128 0 : return true;
6129 : }
6130 :
6131 4 : static bool test_AddPerMachineConnection(struct torture_context *tctx,
6132 : struct dcerpc_binding_handle *b,
6133 : const char *servername,
6134 : const char *printername,
6135 : const char *printserver,
6136 : const char *provider,
6137 : WERROR expected_error)
6138 : {
6139 0 : struct spoolss_AddPerMachineConnection r;
6140 4 : const char *composed_printername = printername;
6141 :
6142 4 : if (servername != NULL) {
6143 0 : composed_printername = talloc_asprintf(tctx, "%s\\%s",
6144 : servername,
6145 : printername);
6146 : }
6147 4 : r.in.server = servername;
6148 4 : r.in.printername = composed_printername;
6149 4 : r.in.printserver = printserver;
6150 4 : r.in.provider = provider;
6151 :
6152 4 : torture_comment(tctx, "Testing AddPerMachineConnection(%s|%s|%s)\n",
6153 : printername, printserver, provider);
6154 :
6155 4 : torture_assert_ntstatus_ok(tctx,
6156 : dcerpc_spoolss_AddPerMachineConnection_r(b, tctx, &r),
6157 : "spoolss_AddPerMachineConnection failed");
6158 0 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6159 : "spoolss_AddPerMachineConnection failed");
6160 :
6161 0 : return true;
6162 : }
6163 :
6164 0 : static bool test_DeletePerMachineConnection(struct torture_context *tctx,
6165 : struct dcerpc_binding_handle *b,
6166 : const char *servername,
6167 : const char *printername,
6168 : WERROR expected_error)
6169 : {
6170 0 : struct spoolss_DeletePerMachineConnection r;
6171 0 : const char *composed_printername = printername;
6172 :
6173 0 : if (servername != NULL) {
6174 0 : composed_printername = talloc_asprintf(tctx, "%s\\%s",
6175 : servername,
6176 : printername);
6177 : }
6178 :
6179 0 : r.in.server = servername;
6180 0 : r.in.printername = composed_printername;
6181 :
6182 0 : torture_comment(tctx, "Testing DeletePerMachineConnection(%s)\n",
6183 : printername);
6184 :
6185 0 : torture_assert_ntstatus_ok(tctx,
6186 : dcerpc_spoolss_DeletePerMachineConnection_r(b, tctx, &r),
6187 : "spoolss_DeletePerMachineConnection failed");
6188 0 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6189 : "spoolss_DeletePerMachineConnection failed");
6190 :
6191 0 : return true;
6192 : }
6193 :
6194 0 : static bool test_EnumPerMachineConnections(struct torture_context *tctx,
6195 : struct dcerpc_binding_handle *b,
6196 : const char *servername)
6197 : {
6198 0 : struct spoolss_EnumPerMachineConnections r;
6199 0 : DATA_BLOB blob = data_blob_null;
6200 0 : struct spoolss_PrinterInfo4 *info;
6201 0 : uint32_t needed;
6202 0 : uint32_t count;
6203 :
6204 0 : r.in.server = servername;
6205 0 : r.in.buffer = &blob;
6206 0 : r.in.offered = 0;
6207 :
6208 0 : r.out.info = &info;
6209 0 : r.out.needed = &needed;
6210 0 : r.out.count = &count;
6211 :
6212 0 : torture_comment(tctx, "Testing EnumPerMachineConnections(%s)\n",
6213 : servername);
6214 :
6215 0 : torture_assert_ntstatus_ok(tctx,
6216 : dcerpc_spoolss_EnumPerMachineConnections_r(b, tctx, &r),
6217 : "spoolss_EnumPerMachineConnections failed");
6218 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
6219 0 : blob = data_blob_talloc_zero(tctx, needed);
6220 0 : r.in.buffer = &blob;
6221 0 : r.in.offered = needed;
6222 :
6223 0 : torture_assert_ntstatus_ok(tctx,
6224 : dcerpc_spoolss_EnumPerMachineConnections_r(b, tctx, &r),
6225 : "spoolss_EnumPerMachineConnections failed");
6226 : }
6227 0 : torture_assert_werr_ok(tctx, r.out.result,
6228 : "spoolss_EnumPerMachineConnections failed");
6229 :
6230 0 : return true;
6231 : }
6232 :
6233 4 : static bool test_addpermachineconnection(struct torture_context *tctx,
6234 : void *private_data)
6235 : {
6236 0 : struct test_spoolss_context *ctx =
6237 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6238 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6239 4 : struct dcerpc_binding_handle *b = p->binding_handle;
6240 4 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
6241 0 : int i;
6242 :
6243 0 : struct {
6244 : const char *servername;
6245 : const char *printername;
6246 : const char *printserver;
6247 : const char *provider;
6248 : WERROR expected_add_result;
6249 : WERROR expected_del_result;
6250 4 : } tests[] = {
6251 : {
6252 : .servername = NULL,
6253 : .printername = "foo",
6254 : .printserver = "",
6255 : .provider = "unknown",
6256 : .expected_add_result = WERR_INVALID_PRINTER_NAME,
6257 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6258 : },{
6259 : .servername = NULL,
6260 : .printername = "Microsoft Print to PDF",
6261 : .printserver = "samba.org",
6262 : .provider = "unknown",
6263 : .expected_add_result = WERR_INVALID_PRINTER_NAME,
6264 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6265 : },{
6266 : .servername = NULL,
6267 : .printername = "Microsoft Print to PDF",
6268 : .printserver = "samba.org",
6269 : .provider = "",
6270 : .expected_add_result = WERR_INVALID_PRINTER_NAME,
6271 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6272 : },{
6273 : .servername = server_name_slash,
6274 : .printername = "foo",
6275 : .printserver = "",
6276 : .provider = "unknown",
6277 : .expected_add_result = WERR_FILE_NOT_FOUND,
6278 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6279 : },{
6280 : .servername = server_name_slash,
6281 : .printername = "foo",
6282 : .printserver = "",
6283 : .provider = "",
6284 : .expected_add_result = WERR_OK,
6285 : .expected_del_result = WERR_OK
6286 : },{
6287 : .servername = server_name_slash,
6288 : .printername = "Microsoft Print to PDF",
6289 : .printserver = "samba.org",
6290 : .provider = "unknown",
6291 : .expected_add_result = WERR_FILE_NOT_FOUND,
6292 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6293 : },{
6294 : .servername = server_name_slash,
6295 : .printername = "Microsoft Print to PDF",
6296 : .printserver = "samba.org",
6297 : .provider = "",
6298 : .expected_add_result = WERR_OK,
6299 : .expected_del_result = WERR_OK
6300 : }
6301 : };
6302 :
6303 4 : for (i=0; i < ARRAY_SIZE(tests); i++) {
6304 4 : torture_assert(tctx,
6305 : test_AddPerMachineConnection(tctx, b,
6306 : tests[i].servername,
6307 : tests[i].printername,
6308 : tests[i].printserver,
6309 : tests[i].provider,
6310 : tests[i].expected_add_result),
6311 : "add per machine connection failed");
6312 0 : torture_assert(tctx,
6313 : test_EnumPerMachineConnections(tctx, b,
6314 : tests[i].servername),
6315 : "enum per machine connections failed");
6316 0 : torture_assert(tctx,
6317 : test_DeletePerMachineConnection(tctx, b,
6318 : tests[i].servername,
6319 : tests[i].printername,
6320 : tests[i].expected_del_result),
6321 : "delete per machine connection failed");
6322 0 : torture_assert(tctx,
6323 : test_EnumPerMachineConnections(tctx, b,
6324 : tests[i].servername),
6325 : "enum per machine connections failed");
6326 : }
6327 :
6328 0 : return true;
6329 : }
6330 :
6331 32 : static bool test_GetChangeID_PrinterData(struct torture_context *tctx,
6332 : struct dcerpc_binding_handle *b,
6333 : struct policy_handle *handle,
6334 : uint32_t *change_id)
6335 : {
6336 0 : enum winreg_Type type;
6337 0 : uint8_t *data;
6338 0 : uint32_t needed;
6339 :
6340 32 : torture_assert(tctx,
6341 : test_GetPrinterData(tctx, b, handle, "ChangeID", &type, &data, &needed),
6342 : "failed to call GetPrinterData");
6343 :
6344 32 : torture_assert(tctx, type == REG_DWORD, "unexpected type");
6345 32 : torture_assert_int_equal(tctx, needed, 4, "unexpected size");
6346 :
6347 32 : *change_id = IVAL(data, 0);
6348 :
6349 32 : return true;
6350 : }
6351 :
6352 32 : static bool test_GetChangeID_PrinterDataEx(struct torture_context *tctx,
6353 : struct dcerpc_pipe *p,
6354 : struct policy_handle *handle,
6355 : uint32_t *change_id)
6356 : {
6357 32 : enum winreg_Type type = REG_NONE;
6358 32 : uint8_t *data = NULL;
6359 32 : uint32_t needed = 0;
6360 :
6361 32 : torture_assert(tctx,
6362 : test_GetPrinterDataEx(tctx, p, handle, "PrinterDriverData", "ChangeID", &type, &data, &needed),
6363 : "failed to call GetPrinterData");
6364 :
6365 32 : torture_assert(tctx, type == REG_DWORD, "unexpected type");
6366 32 : torture_assert_int_equal(tctx, needed, 4, "unexpected size");
6367 :
6368 32 : *change_id = IVAL(data, 0);
6369 :
6370 32 : return true;
6371 : }
6372 :
6373 32 : static bool test_GetChangeID_PrinterInfo(struct torture_context *tctx,
6374 : struct dcerpc_binding_handle *b,
6375 : struct policy_handle *handle,
6376 : uint32_t *change_id)
6377 : {
6378 0 : union spoolss_PrinterInfo info;
6379 :
6380 32 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 0, &info),
6381 : "failed to query Printer level 0");
6382 :
6383 32 : *change_id = info.info0.change_id;
6384 :
6385 32 : return true;
6386 : }
6387 :
6388 8 : static bool test_ChangeID(struct torture_context *tctx,
6389 : struct dcerpc_pipe *p,
6390 : struct policy_handle *handle)
6391 : {
6392 0 : uint32_t change_id, change_id_ex, change_id_info;
6393 0 : uint32_t change_id2, change_id_ex2, change_id_info2;
6394 0 : union spoolss_PrinterInfo info;
6395 0 : const char *comment;
6396 8 : struct dcerpc_binding_handle *b = p->binding_handle;
6397 :
6398 8 : torture_comment(tctx, "Testing ChangeID: id change test #1\n");
6399 :
6400 8 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
6401 : "failed to query for ChangeID");
6402 8 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
6403 : "failed to query for ChangeID");
6404 8 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
6405 : "failed to query for ChangeID");
6406 :
6407 8 : torture_assert_int_equal(tctx, change_id, change_id_ex,
6408 : "change_ids should all be equal");
6409 8 : torture_assert_int_equal(tctx, change_id_ex, change_id_info,
6410 : "change_ids should all be equal");
6411 :
6412 :
6413 8 : torture_comment(tctx, "Testing ChangeID: id change test #2\n");
6414 :
6415 8 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
6416 : "failed to query for ChangeID");
6417 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
6418 : "failed to query Printer level 2");
6419 8 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
6420 : "failed to query for ChangeID");
6421 8 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
6422 : "failed to query for ChangeID");
6423 8 : torture_assert_int_equal(tctx, change_id, change_id_ex,
6424 : "change_id should not have changed");
6425 8 : torture_assert_int_equal(tctx, change_id_ex, change_id_info,
6426 : "change_id should not have changed");
6427 :
6428 :
6429 8 : torture_comment(tctx, "Testing ChangeID: id change test #3\n");
6430 :
6431 8 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
6432 : "failed to query for ChangeID");
6433 8 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
6434 : "failed to query for ChangeID");
6435 8 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
6436 : "failed to query for ChangeID");
6437 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
6438 : "failed to query Printer level 2");
6439 8 : comment = talloc_strdup(tctx, info.info2.comment);
6440 :
6441 : {
6442 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
6443 0 : struct spoolss_DevmodeContainer devmode_ctr;
6444 0 : struct sec_desc_buf secdesc_ctr;
6445 0 : union spoolss_SetPrinterInfo sinfo;
6446 :
6447 8 : ZERO_STRUCT(info_ctr);
6448 8 : ZERO_STRUCT(devmode_ctr);
6449 8 : ZERO_STRUCT(secdesc_ctr);
6450 :
6451 :
6452 8 : torture_assert(tctx, PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
6453 8 : sinfo.info2->comment = "torture_comment";
6454 :
6455 8 : info_ctr.level = 2;
6456 8 : info_ctr.info = sinfo;
6457 :
6458 8 : torture_assert(tctx, test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
6459 : "failed to call SetPrinter");
6460 :
6461 8 : sinfo.info2->comment = comment;
6462 :
6463 8 : torture_assert(tctx, test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
6464 : "failed to call SetPrinter");
6465 :
6466 : }
6467 :
6468 8 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id2),
6469 : "failed to query for ChangeID");
6470 8 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex2),
6471 : "failed to query for ChangeID");
6472 8 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info2),
6473 : "failed to query for ChangeID");
6474 :
6475 8 : torture_assert_int_equal(tctx, change_id2, change_id_ex2,
6476 : "change_ids should all be equal");
6477 8 : torture_assert_int_equal(tctx, change_id_ex2, change_id_info2,
6478 : "change_ids should all be equal");
6479 :
6480 8 : torture_assert(tctx, (change_id < change_id2),
6481 : talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
6482 : change_id2, change_id));
6483 8 : torture_assert(tctx, (change_id_ex < change_id_ex2),
6484 : talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
6485 : change_id_ex2, change_id_ex));
6486 8 : torture_assert(tctx, (change_id_info < change_id_info2),
6487 : talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
6488 : change_id_info2, change_id_info));
6489 :
6490 8 : torture_comment(tctx, "ChangeID tests succeeded\n\n");
6491 :
6492 8 : return true;
6493 : }
6494 :
6495 0 : static bool test_SecondaryClosePrinter(struct torture_context *tctx,
6496 : struct dcerpc_pipe *p,
6497 : struct policy_handle *handle)
6498 : {
6499 0 : NTSTATUS status;
6500 0 : struct cli_credentials *anon_creds;
6501 0 : const struct dcerpc_binding *binding2;
6502 0 : struct dcerpc_pipe *p2;
6503 0 : struct spoolss_ClosePrinter cp;
6504 :
6505 : /* only makes sense on SMB */
6506 0 : if (p->conn->transport.transport != NCACN_NP) {
6507 0 : return true;
6508 : }
6509 :
6510 0 : torture_comment(tctx, "Testing close on secondary pipe\n");
6511 :
6512 0 : anon_creds = cli_credentials_init_anon(tctx);
6513 0 : torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
6514 :
6515 0 : binding2 = p->binding;
6516 0 : status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_spoolss,
6517 : anon_creds, tctx->lp_ctx,
6518 : tctx, &p2);
6519 0 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
6520 :
6521 0 : cp.in.handle = handle;
6522 0 : cp.out.handle = handle;
6523 :
6524 0 : status = dcerpc_spoolss_ClosePrinter_r(p2->binding_handle, tctx, &cp);
6525 0 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH,
6526 : "ERROR: Allowed close on secondary connection");
6527 :
6528 0 : talloc_free(p2);
6529 :
6530 0 : return true;
6531 : }
6532 :
6533 28 : static bool test_OpenPrinter_badname(struct torture_context *tctx,
6534 : struct dcerpc_binding_handle *b, const char *name)
6535 : {
6536 0 : NTSTATUS status;
6537 0 : struct spoolss_OpenPrinter op;
6538 0 : struct spoolss_OpenPrinterEx opEx;
6539 0 : struct policy_handle handle;
6540 28 : bool ret = true;
6541 :
6542 28 : op.in.printername = name;
6543 28 : op.in.datatype = NULL;
6544 28 : op.in.devmode_ctr.devmode= NULL;
6545 28 : op.in.access_mask = 0;
6546 28 : op.out.handle = &handle;
6547 :
6548 28 : torture_comment(tctx, "Testing OpenPrinter(%s) with bad name\n", op.in.printername);
6549 :
6550 28 : status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &op);
6551 28 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
6552 28 : torture_assert_werr_equal(tctx, op.out.result, WERR_INVALID_PRINTER_NAME,
6553 : "unexpected result");
6554 :
6555 28 : if (W_ERROR_IS_OK(op.out.result)) {
6556 0 : ret &=test_ClosePrinter(tctx, b, &handle);
6557 : }
6558 :
6559 28 : opEx.in.printername = name;
6560 28 : opEx.in.datatype = NULL;
6561 28 : opEx.in.devmode_ctr.devmode = NULL;
6562 28 : opEx.in.access_mask = 0;
6563 28 : opEx.in.userlevel_ctr.level = 1;
6564 28 : opEx.in.userlevel_ctr.user_info.level1 = NULL;
6565 28 : opEx.out.handle = &handle;
6566 :
6567 28 : torture_comment(tctx, "Testing OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
6568 :
6569 28 : status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &opEx);
6570 28 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
6571 28 : torture_assert_werr_equal(tctx, opEx.out.result, WERR_INVALID_PARAMETER,
6572 : "unexpected result");
6573 :
6574 28 : if (W_ERROR_IS_OK(opEx.out.result)) {
6575 0 : ret &=test_ClosePrinter(tctx, b, &handle);
6576 : }
6577 :
6578 28 : return ret;
6579 : }
6580 :
6581 4 : static bool test_OpenPrinter_badname_list(struct torture_context *tctx,
6582 : void *private_data)
6583 : {
6584 0 : struct test_spoolss_context *ctx =
6585 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6586 :
6587 4 : const char *badnames[] = {
6588 : "__INVALID_PRINTER__",
6589 : "\\\\__INVALID_HOST__",
6590 : "",
6591 : "\\\\\\",
6592 : "\\\\\\__INVALID_PRINTER__"
6593 : };
6594 0 : const char *badname;
6595 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6596 4 : const char *server_name = dcerpc_server_name(p);
6597 4 : struct dcerpc_binding_handle *b = p->binding_handle;
6598 0 : int i;
6599 :
6600 24 : for (i=0; i < ARRAY_SIZE(badnames); i++) {
6601 20 : torture_assert(tctx,
6602 : test_OpenPrinter_badname(tctx, b, badnames[i]),
6603 : "");
6604 : }
6605 :
6606 4 : badname = talloc_asprintf(tctx, "\\\\%s\\", server_name);
6607 4 : torture_assert(tctx,
6608 : test_OpenPrinter_badname(tctx, b, badname),
6609 : "");
6610 :
6611 4 : badname = talloc_asprintf(tctx, "\\\\%s\\__INVALID_PRINTER__", server_name);
6612 4 : torture_assert(tctx,
6613 : test_OpenPrinter_badname(tctx, b, badname),
6614 : "");
6615 :
6616 4 : return true;
6617 : }
6618 :
6619 60 : static bool test_OpenPrinter(struct torture_context *tctx,
6620 : struct dcerpc_pipe *p,
6621 : const char *name,
6622 : const char *environment,
6623 : bool open_only)
6624 : {
6625 0 : NTSTATUS status;
6626 0 : struct spoolss_OpenPrinter r;
6627 0 : struct policy_handle handle;
6628 60 : bool ret = true;
6629 60 : struct dcerpc_binding_handle *b = p->binding_handle;
6630 :
6631 60 : r.in.printername = name;
6632 60 : r.in.datatype = NULL;
6633 60 : r.in.devmode_ctr.devmode= NULL;
6634 60 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6635 60 : r.out.handle = &handle;
6636 :
6637 60 : torture_comment(tctx, "Testing OpenPrinter(%s)\n", r.in.printername);
6638 :
6639 60 : status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &r);
6640 :
6641 60 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
6642 :
6643 60 : torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed");
6644 :
6645 60 : if (open_only) {
6646 40 : goto close_printer;
6647 : }
6648 :
6649 20 : if (!test_GetPrinter(tctx, b, &handle, environment)) {
6650 0 : ret = false;
6651 : }
6652 :
6653 20 : if (!torture_setting_bool(tctx, "samba3", false)) {
6654 0 : if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
6655 0 : ret = false;
6656 : }
6657 : }
6658 :
6659 20 : close_printer:
6660 60 : if (!test_ClosePrinter(tctx, b, &handle)) {
6661 0 : ret = false;
6662 : }
6663 :
6664 60 : return ret;
6665 : }
6666 :
6667 664 : static bool test_OpenPrinterEx(struct torture_context *tctx,
6668 : struct dcerpc_binding_handle *b,
6669 : const char *printername,
6670 : const char *datatype,
6671 : struct spoolss_DeviceMode *devmode,
6672 : uint32_t access_mask,
6673 : struct spoolss_UserLevelCtr *userlevel_ctr,
6674 : struct policy_handle *handle,
6675 : WERROR expected_result)
6676 : {
6677 0 : struct spoolss_OpenPrinterEx r;
6678 :
6679 664 : r.in.printername = printername;
6680 664 : r.in.datatype = datatype;
6681 664 : r.in.devmode_ctr.devmode= devmode;
6682 664 : r.in.access_mask = access_mask;
6683 664 : r.in.userlevel_ctr = *userlevel_ctr;
6684 664 : r.out.handle = handle;
6685 :
6686 664 : torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername);
6687 :
6688 664 : torture_assert_ntstatus_ok(tctx,
6689 : dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r),
6690 : "OpenPrinterEx failed");
6691 :
6692 664 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
6693 : "OpenPrinterEx failed");
6694 :
6695 664 : return true;
6696 : }
6697 :
6698 104 : static bool call_OpenPrinterEx(struct torture_context *tctx,
6699 : struct dcerpc_pipe *p,
6700 : const char *name,
6701 : struct spoolss_DeviceMode *devmode,
6702 : struct policy_handle *handle)
6703 : {
6704 0 : struct spoolss_UserLevelCtr userlevel_ctr;
6705 0 : struct spoolss_UserLevel1 userlevel1;
6706 104 : struct dcerpc_binding_handle *b = p->binding_handle;
6707 :
6708 104 : userlevel1.size = 1234;
6709 104 : userlevel1.client = "hello";
6710 104 : userlevel1.user = "spottyfoot!";
6711 104 : userlevel1.build = 1;
6712 104 : userlevel1.major = 2;
6713 104 : userlevel1.minor = 3;
6714 104 : userlevel1.processor = 4;
6715 :
6716 104 : userlevel_ctr.level = 1;
6717 104 : userlevel_ctr.user_info.level1 = &userlevel1;
6718 :
6719 208 : return test_OpenPrinterEx(tctx, b, name, NULL, devmode,
6720 : SEC_FLAG_MAXIMUM_ALLOWED,
6721 : &userlevel_ctr,
6722 : handle,
6723 104 : WERR_OK);
6724 : }
6725 :
6726 8 : static bool test_printer_rename(struct torture_context *tctx,
6727 : void *private_data)
6728 : {
6729 0 : struct torture_printer_context *t =
6730 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
6731 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
6732 :
6733 8 : bool ret = true;
6734 0 : union spoolss_PrinterInfo info;
6735 0 : union spoolss_SetPrinterInfo sinfo;
6736 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
6737 0 : struct spoolss_DevmodeContainer devmode_ctr;
6738 0 : struct sec_desc_buf secdesc_ctr;
6739 0 : const char *printer_name;
6740 0 : const char *printer_name_orig;
6741 8 : const char *printer_name_new = "SAMBA smbtorture Test Printer (Copy 2)";
6742 0 : struct policy_handle new_handle;
6743 0 : const char *q;
6744 8 : struct dcerpc_binding_handle *b = p->binding_handle;
6745 :
6746 8 : ZERO_STRUCT(devmode_ctr);
6747 8 : ZERO_STRUCT(secdesc_ctr);
6748 :
6749 8 : torture_comment(tctx, "Testing Printer rename operations\n");
6750 :
6751 8 : torture_assert(tctx,
6752 : test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
6753 : "failed to call GetPrinter level 2");
6754 :
6755 8 : printer_name_orig = talloc_strdup(tctx, info.info2.printername);
6756 :
6757 8 : q = strrchr(info.info2.printername, '\\');
6758 8 : if (q) {
6759 8 : torture_warning(tctx,
6760 : "server returns printername %s incl. servername although we did not set servername", info.info2.printername);
6761 : }
6762 :
6763 8 : torture_assert(tctx,
6764 : PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
6765 :
6766 8 : sinfo.info2->printername = printer_name_new;
6767 :
6768 8 : info_ctr.level = 2;
6769 8 : info_ctr.info = sinfo;
6770 :
6771 8 : torture_assert(tctx,
6772 : test_SetPrinter(tctx, b, &t->handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
6773 : "failed to call SetPrinter level 2");
6774 :
6775 8 : torture_assert(tctx,
6776 : test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
6777 : "failed to call GetPrinter level 2");
6778 :
6779 8 : printer_name = talloc_strdup(tctx, info.info2.printername);
6780 :
6781 8 : q = strrchr(info.info2.printername, '\\');
6782 8 : if (q) {
6783 8 : torture_warning(tctx,
6784 : "server returns printername %s incl. servername although we did not set servername", info.info2.printername);
6785 8 : q++;
6786 8 : printer_name = q;
6787 : }
6788 :
6789 8 : torture_assert_str_equal(tctx, printer_name, printer_name_new,
6790 : "new printer name was not set");
6791 :
6792 : /* samba currently cannot fully rename printers */
6793 8 : if (!torture_setting_bool(tctx, "samba3", false)) {
6794 0 : torture_assert(tctx,
6795 : test_OpenPrinter_badname(tctx, b, printer_name_orig),
6796 : "still can open printer with oldname after rename");
6797 : } else {
6798 8 : torture_warning(tctx, "*not* checking for open with oldname after rename for samba3");
6799 : }
6800 :
6801 8 : torture_assert(tctx,
6802 : call_OpenPrinterEx(tctx, p, printer_name_new, NULL, &new_handle),
6803 : "failed to open printer with new name");
6804 :
6805 8 : torture_assert(tctx,
6806 : test_GetPrinter_level(tctx, b, &new_handle, 2, &info),
6807 : "failed to call GetPrinter level 2");
6808 :
6809 8 : torture_assert_str_equal(tctx, info.info2.printername, printer_name_new,
6810 : "new printer name was not set");
6811 :
6812 8 : torture_assert(tctx,
6813 : test_ClosePrinter(tctx, b, &new_handle),
6814 : "failed to close printer");
6815 :
6816 8 : torture_comment(tctx, "Printer rename operations test succeeded\n\n");
6817 :
6818 8 : return ret;
6819 : }
6820 :
6821 28 : static bool test_openprinter(struct torture_context *tctx,
6822 : struct dcerpc_binding_handle *b,
6823 : const char *real_printername)
6824 : {
6825 0 : struct spoolss_UserLevelCtr userlevel_ctr;
6826 0 : struct policy_handle handle;
6827 0 : struct spoolss_UserLevel1 userlevel1;
6828 28 : const char *printername = NULL;
6829 0 : int i;
6830 :
6831 0 : struct {
6832 : const char *suffix;
6833 : WERROR expected_result;
6834 28 : } tests[] = {
6835 : {
6836 : .suffix = "rubbish",
6837 : .expected_result = WERR_INVALID_PRINTER_NAME
6838 : },{
6839 : .suffix = ", LocalOnl",
6840 : .expected_result = WERR_INVALID_PRINTER_NAME
6841 : },{
6842 : .suffix = ", localOnly",
6843 : .expected_result = WERR_INVALID_PRINTER_NAME
6844 : },{
6845 : .suffix = ", localonl",
6846 : .expected_result = WERR_INVALID_PRINTER_NAME
6847 : },{
6848 : .suffix = ",LocalOnl",
6849 : .expected_result = WERR_INVALID_PRINTER_NAME
6850 : },{
6851 : .suffix = ",localOnl2",
6852 : .expected_result = WERR_INVALID_PRINTER_NAME
6853 : },{
6854 : .suffix = ", DrvConver2t",
6855 : .expected_result = WERR_INVALID_PRINTER_NAME
6856 : },{
6857 : .suffix = ", drvconvert",
6858 : .expected_result = WERR_INVALID_PRINTER_NAME
6859 : },{
6860 : .suffix = ",drvconvert",
6861 : .expected_result = WERR_INVALID_PRINTER_NAME
6862 : },{
6863 : .suffix = ", DrvConvert",
6864 : .expected_result = WERR_OK
6865 : },{
6866 : .suffix = " , DrvConvert",
6867 : .expected_result = WERR_INVALID_PRINTER_NAME
6868 : },{
6869 : .suffix = ",DrvConvert",
6870 : .expected_result = WERR_OK
6871 : },{
6872 : .suffix = ", DrvConvertsadfasdf",
6873 : .expected_result = WERR_OK
6874 : },{
6875 : .suffix = ",DrvConvertasdfasd",
6876 : .expected_result = WERR_OK
6877 : },{
6878 : .suffix = ", LocalOnly",
6879 : .expected_result = WERR_OK
6880 : },{
6881 : .suffix = " , LocalOnly",
6882 : .expected_result = WERR_INVALID_PRINTER_NAME
6883 : },{
6884 : .suffix = ",LocalOnly",
6885 : .expected_result = WERR_OK
6886 : },{
6887 : .suffix = ", LocalOnlysagi4gjfkd",
6888 : .expected_result = WERR_OK
6889 : },{
6890 : .suffix = ",LocalOnlysagi4gjfkd",
6891 : .expected_result = WERR_OK
6892 : }
6893 : };
6894 :
6895 28 : userlevel1.size = 1234;
6896 28 : userlevel1.client = "hello";
6897 28 : userlevel1.user = "spottyfoot!";
6898 28 : userlevel1.build = 1;
6899 28 : userlevel1.major = 2;
6900 28 : userlevel1.minor = 3;
6901 28 : userlevel1.processor = 4;
6902 :
6903 28 : userlevel_ctr.level = 1;
6904 28 : userlevel_ctr.user_info.level1 = &userlevel1;
6905 :
6906 28 : torture_comment(tctx, "Testing openprinterex printername pattern\n");
6907 :
6908 28 : torture_assert(tctx,
6909 : test_OpenPrinterEx(tctx, b, real_printername, NULL, NULL, 0,
6910 : &userlevel_ctr, &handle,
6911 : WERR_OK),
6912 : "OpenPrinterEx failed");
6913 28 : test_ClosePrinter(tctx, b, &handle);
6914 :
6915 560 : for (i=0; i < ARRAY_SIZE(tests); i++) {
6916 :
6917 532 : printername = talloc_asprintf(tctx, "%s%s",
6918 : real_printername,
6919 : tests[i].suffix);
6920 :
6921 532 : torture_assert(tctx,
6922 : test_OpenPrinterEx(tctx, b, printername, NULL, NULL, 0,
6923 : &userlevel_ctr, &handle,
6924 : tests[i].expected_result),
6925 : "OpenPrinterEx failed");
6926 532 : if (W_ERROR_IS_OK(tests[i].expected_result)) {
6927 224 : test_ClosePrinter(tctx, b, &handle);
6928 : }
6929 : }
6930 :
6931 28 : return true;
6932 : }
6933 :
6934 :
6935 20 : static bool test_existing_printer_openprinterex(struct torture_context *tctx,
6936 : struct dcerpc_pipe *p,
6937 : const char *name,
6938 : const char *environment)
6939 : {
6940 0 : struct policy_handle handle;
6941 20 : bool ret = true;
6942 20 : struct dcerpc_binding_handle *b = p->binding_handle;
6943 :
6944 20 : if (!test_openprinter(tctx, b, name)) {
6945 0 : return false;
6946 : }
6947 :
6948 20 : if (!call_OpenPrinterEx(tctx, p, name, NULL, &handle)) {
6949 0 : return false;
6950 : }
6951 :
6952 20 : if (!test_PrinterInfo_SD(tctx, b, &handle)) {
6953 0 : ret = false;
6954 : }
6955 :
6956 20 : if (!test_GetPrinter(tctx, b, &handle, environment)) {
6957 0 : ret = false;
6958 : }
6959 :
6960 20 : if (!test_EnumForms_all(tctx, b, &handle, false)) {
6961 0 : ret = false;
6962 : }
6963 :
6964 20 : if (!test_Forms(tctx, b, &handle, false, name, NULL, NULL)) {
6965 0 : ret = false;
6966 : }
6967 :
6968 20 : if (!test_Forms_winreg(tctx, b, &handle, false, name)) {
6969 0 : ret = false;
6970 : }
6971 :
6972 20 : if (!test_EnumPrinterData_all(tctx, p, &handle)) {
6973 0 : ret = false;
6974 : }
6975 :
6976 20 : if (!test_EnumPrinterDataEx(tctx, b, &handle, "PrinterDriverData", NULL, NULL)) {
6977 0 : ret = false;
6978 : }
6979 :
6980 20 : if (!test_EnumPrinterData_consistency(tctx, p, &handle)) {
6981 0 : ret = false;
6982 : }
6983 :
6984 20 : if (!test_printer_all_keys(tctx, b, &handle)) {
6985 0 : ret = false;
6986 : }
6987 :
6988 20 : if (!test_PausePrinter(tctx, b, &handle)) {
6989 0 : ret = false;
6990 : }
6991 :
6992 20 : if (!test_DoPrintTest(tctx, b, &handle)) {
6993 10 : ret = false;
6994 : }
6995 :
6996 20 : if (!test_ResumePrinter(tctx, b, &handle)) {
6997 0 : ret = false;
6998 : }
6999 :
7000 20 : if (!test_SetPrinterData_matrix(tctx, b, &handle, name, NULL, NULL)) {
7001 0 : ret = false;
7002 : }
7003 :
7004 20 : if (!test_SetPrinterDataEx_matrix(tctx, p, &handle, name, NULL, NULL)) {
7005 0 : ret = false;
7006 : }
7007 :
7008 20 : if (!torture_setting_bool(tctx, "samba3", false)) {
7009 0 : if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
7010 0 : ret = false;
7011 : }
7012 : }
7013 :
7014 20 : if (!test_ClosePrinter(tctx, b, &handle)) {
7015 0 : ret = false;
7016 : }
7017 :
7018 20 : return ret;
7019 : }
7020 :
7021 4 : static bool test_EnumPrinters_old(struct torture_context *tctx,
7022 : void *private_data)
7023 : {
7024 0 : struct test_spoolss_context *ctx =
7025 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
7026 0 : struct spoolss_EnumPrinters r;
7027 0 : NTSTATUS status;
7028 4 : uint16_t levels[] = {1, 2, 4, 5};
7029 0 : int i;
7030 4 : bool ret = true;
7031 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
7032 4 : struct dcerpc_binding_handle *b = p->binding_handle;
7033 :
7034 20 : for (i=0;i<ARRAY_SIZE(levels);i++) {
7035 0 : union spoolss_PrinterInfo *info;
7036 0 : int j;
7037 0 : uint32_t needed;
7038 0 : uint32_t count;
7039 :
7040 16 : r.in.flags = PRINTER_ENUM_LOCAL;
7041 16 : r.in.server = "";
7042 16 : r.in.level = levels[i];
7043 16 : r.in.buffer = NULL;
7044 16 : r.in.offered = 0;
7045 16 : r.out.needed = &needed;
7046 16 : r.out.count = &count;
7047 16 : r.out.info = &info;
7048 :
7049 16 : torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
7050 :
7051 16 : status = dcerpc_spoolss_EnumPrinters_r(b, tctx, &r);
7052 16 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
7053 :
7054 16 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7055 16 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7056 16 : r.in.buffer = &blob;
7057 16 : r.in.offered = needed;
7058 16 : status = dcerpc_spoolss_EnumPrinters_r(b, tctx, &r);
7059 : }
7060 :
7061 16 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
7062 :
7063 16 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
7064 :
7065 16 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
7066 :
7067 16 : if (!info) {
7068 0 : torture_comment(tctx, "No printers returned\n");
7069 0 : return true;
7070 : }
7071 :
7072 96 : for (j=0;j<count;j++) {
7073 80 : if (r.in.level == 1) {
7074 20 : char *unc = talloc_strdup(tctx, info[j].info1.name);
7075 0 : char *slash, *name, *full_name;
7076 20 : name = unc;
7077 20 : if (unc[0] == '\\' && unc[1] == '\\') {
7078 0 : unc +=2;
7079 : }
7080 20 : slash = strchr(unc, '\\');
7081 20 : if (slash) {
7082 0 : slash++;
7083 0 : name = slash;
7084 : }
7085 20 : full_name = talloc_asprintf(tctx, "\\\\%s\\%s",
7086 : dcerpc_server_name(p), name);
7087 20 : if (!test_OpenPrinter(tctx, p, name, ctx->environment, true)) {
7088 0 : ret = false;
7089 : }
7090 20 : if (!test_OpenPrinter(tctx, p, full_name, ctx->environment, true)) {
7091 0 : ret = false;
7092 : }
7093 20 : if (!test_OpenPrinter(tctx, p, name, ctx->environment, false)) {
7094 0 : ret = false;
7095 : }
7096 20 : if (!test_existing_printer_openprinterex(tctx, p, name, ctx->environment)) {
7097 10 : ret = false;
7098 : }
7099 : }
7100 : }
7101 : }
7102 :
7103 4 : return ret;
7104 : }
7105 :
7106 8 : static bool test_EnumPrinters_level(struct torture_context *tctx,
7107 : struct dcerpc_binding_handle *b,
7108 : uint32_t flags,
7109 : const char *servername,
7110 : uint32_t level,
7111 : uint32_t *count_p,
7112 : union spoolss_PrinterInfo **info_p)
7113 : {
7114 0 : struct spoolss_EnumPrinters r;
7115 0 : union spoolss_PrinterInfo *info;
7116 0 : uint32_t needed;
7117 0 : uint32_t count;
7118 :
7119 8 : r.in.flags = flags;
7120 8 : r.in.server = servername;
7121 8 : r.in.level = level;
7122 8 : r.in.buffer = NULL;
7123 8 : r.in.offered = 0;
7124 8 : r.out.needed = &needed;
7125 8 : r.out.count = &count;
7126 8 : r.out.info = &info;
7127 :
7128 8 : torture_comment(tctx, "Testing EnumPrinters(%s) level %u\n",
7129 : r.in.server, r.in.level);
7130 :
7131 8 : torture_assert_ntstatus_ok(tctx,
7132 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
7133 : "EnumPrinters failed");
7134 8 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7135 8 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7136 8 : r.in.buffer = &blob;
7137 8 : r.in.offered = needed;
7138 8 : torture_assert_ntstatus_ok(tctx,
7139 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
7140 : "EnumPrinters failed");
7141 : }
7142 :
7143 8 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
7144 :
7145 8 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
7146 :
7147 8 : if (count_p) {
7148 8 : *count_p = count;
7149 : }
7150 8 : if (info_p) {
7151 8 : *info_p = info;
7152 : }
7153 :
7154 8 : return true;
7155 : }
7156 :
7157 40 : static const char *get_short_printername(struct torture_context *tctx,
7158 : const char *name)
7159 : {
7160 0 : const char *short_name;
7161 :
7162 40 : if (name[0] == '\\' && name[1] == '\\') {
7163 20 : name += 2;
7164 20 : short_name = strchr(name, '\\');
7165 20 : if (short_name) {
7166 20 : return talloc_strdup(tctx, short_name+1);
7167 : }
7168 : }
7169 :
7170 20 : return name;
7171 : }
7172 :
7173 40 : static const char *get_full_printername(struct torture_context *tctx,
7174 : const char *name)
7175 : {
7176 40 : const char *full_name = talloc_strdup(tctx, name);
7177 0 : char *p;
7178 :
7179 40 : if (name && name[0] == '\\' && name[1] == '\\') {
7180 20 : name += 2;
7181 20 : p = strchr(name, '\\');
7182 20 : if (p) {
7183 20 : return full_name;
7184 : }
7185 : }
7186 :
7187 20 : return NULL;
7188 : }
7189 :
7190 40 : static bool test_OnePrinter_servername(struct torture_context *tctx,
7191 : struct dcerpc_pipe *p,
7192 : struct dcerpc_binding_handle *b,
7193 : const char *servername,
7194 : const char *printername)
7195 : {
7196 0 : union spoolss_PrinterInfo info;
7197 40 : const char *short_name = get_short_printername(tctx, printername);
7198 40 : const char *full_name = get_full_printername(tctx, printername);
7199 :
7200 40 : if (short_name) {
7201 0 : struct policy_handle handle;
7202 40 : torture_assert(tctx,
7203 : call_OpenPrinterEx(tctx, p, short_name, NULL, &handle),
7204 : "failed to open printer");
7205 :
7206 40 : torture_assert(tctx,
7207 : test_GetPrinter_level(tctx, b, &handle, 2, &info),
7208 : "failed to get printer info");
7209 :
7210 40 : torture_assert_casestr_equal(tctx, info.info2.servername, NULL,
7211 : "unexpected servername");
7212 40 : torture_assert_casestr_equal(tctx, info.info2.printername, short_name,
7213 : "unexpected printername");
7214 :
7215 40 : if (info.info2.devmode) {
7216 0 : const char *expected_devicename;
7217 36 : expected_devicename = talloc_strndup(tctx, short_name, MIN(strlen(short_name), 31));
7218 36 : torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
7219 : "unexpected devicemode devicename");
7220 : }
7221 :
7222 40 : torture_assert(tctx,
7223 : test_ClosePrinter(tctx, b, &handle),
7224 : "failed to close printer");
7225 : }
7226 :
7227 40 : if (full_name) {
7228 0 : struct policy_handle handle;
7229 :
7230 20 : torture_assert(tctx,
7231 : call_OpenPrinterEx(tctx, p, full_name, NULL, &handle),
7232 : "failed to open printer");
7233 :
7234 20 : torture_assert(tctx,
7235 : test_GetPrinter_level(tctx, b, &handle, 2, &info),
7236 : "failed to get printer info");
7237 :
7238 20 : torture_assert_casestr_equal(tctx, info.info2.servername, servername,
7239 : "unexpected servername");
7240 20 : torture_assert_casestr_equal(tctx, info.info2.printername, full_name,
7241 : "unexpected printername");
7242 :
7243 20 : if (info.info2.devmode) {
7244 0 : const char *expected_devicename;
7245 18 : expected_devicename = talloc_strndup(tctx, full_name, MIN(strlen(full_name), 31));
7246 18 : torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
7247 : "unexpected devicemode devicename");
7248 : }
7249 :
7250 20 : torture_assert(tctx,
7251 : test_ClosePrinter(tctx, b, &handle),
7252 : "failed to close printer");
7253 : }
7254 :
7255 40 : return true;
7256 : }
7257 :
7258 4 : static bool test_EnumPrinters_servername(struct torture_context *tctx,
7259 : void *private_data)
7260 : {
7261 0 : struct test_spoolss_context *ctx =
7262 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
7263 0 : int i;
7264 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
7265 4 : struct dcerpc_binding_handle *b = p->binding_handle;
7266 0 : uint32_t count;
7267 0 : union spoolss_PrinterInfo *info;
7268 0 : const char *servername;
7269 4 : uint32_t flags = PRINTER_ENUM_NAME|PRINTER_ENUM_LOCAL;
7270 :
7271 4 : torture_comment(tctx, "Testing servername behaviour in EnumPrinters and GetPrinters\n");
7272 :
7273 4 : servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
7274 :
7275 4 : torture_assert(tctx,
7276 : test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
7277 : "failed to enumerate printers");
7278 :
7279 24 : for (i=0; i < count; i++) {
7280 :
7281 20 : torture_assert_casestr_equal(tctx, info[i].info2.servername, servername,
7282 : "unexpected servername");
7283 :
7284 20 : torture_assert(tctx,
7285 : test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
7286 : "failed to check printer");
7287 : }
7288 :
7289 4 : servername = "";
7290 :
7291 4 : torture_assert(tctx,
7292 : test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
7293 : "failed to enumerate printers");
7294 :
7295 24 : for (i=0; i < count; i++) {
7296 :
7297 20 : torture_assert_casestr_equal(tctx, info[i].info2.servername, NULL,
7298 : "unexpected servername");
7299 :
7300 20 : torture_assert(tctx,
7301 : test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
7302 : "failed to check printer");
7303 : }
7304 :
7305 :
7306 4 : return true;
7307 : }
7308 :
7309 : #if 0
7310 : static bool test_GetPrinterDriver(struct torture_context *tctx,
7311 : struct dcerpc_binding_handle *b,
7312 : struct policy_handle *handle,
7313 : const char *driver_name)
7314 : {
7315 : struct spoolss_GetPrinterDriver r;
7316 : uint32_t needed;
7317 :
7318 : r.in.handle = handle;
7319 : r.in.architecture = "W32X86";
7320 : r.in.level = 1;
7321 : r.in.buffer = NULL;
7322 : r.in.offered = 0;
7323 : r.out.needed = &needed;
7324 :
7325 : torture_comment(tctx, "Testing GetPrinterDriver level %d\n", r.in.level);
7326 :
7327 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver_r(b, tctx, &r),
7328 : "failed to call GetPrinterDriver");
7329 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7330 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7331 : r.in.buffer = &blob;
7332 : r.in.offered = needed;
7333 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver_r(b, tctx, &r),
7334 : "failed to call GetPrinterDriver");
7335 : }
7336 :
7337 : torture_assert_werr_ok(tctx, r.out.result,
7338 : "failed to call GetPrinterDriver");
7339 :
7340 : CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
7341 :
7342 : return true;
7343 : }
7344 : #endif
7345 :
7346 0 : static bool test_GetPrinterDriver2_level(struct torture_context *tctx,
7347 : struct dcerpc_binding_handle *b,
7348 : struct policy_handle *handle,
7349 : const char *driver_name,
7350 : const char *architecture,
7351 : uint32_t level,
7352 : uint32_t client_major_version,
7353 : uint32_t client_minor_version,
7354 : union spoolss_DriverInfo *info_p,
7355 : WERROR *result_p)
7356 :
7357 : {
7358 0 : struct spoolss_GetPrinterDriver2 r;
7359 0 : uint32_t needed;
7360 0 : uint32_t server_major_version;
7361 0 : uint32_t server_minor_version;
7362 :
7363 0 : r.in.handle = handle;
7364 0 : r.in.architecture = architecture;
7365 0 : r.in.client_major_version = client_major_version;
7366 0 : r.in.client_minor_version = client_minor_version;
7367 0 : r.in.buffer = NULL;
7368 0 : r.in.offered = 0;
7369 0 : r.in.level = level;
7370 0 : r.out.needed = &needed;
7371 0 : r.out.server_major_version = &server_major_version;
7372 0 : r.out.server_minor_version = &server_minor_version;
7373 :
7374 0 : torture_comment(tctx, "Testing GetPrinterDriver2(%s) level %d\n",
7375 : driver_name, r.in.level);
7376 :
7377 0 : torture_assert_ntstatus_ok(tctx,
7378 : dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &r),
7379 : "failed to call GetPrinterDriver2");
7380 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7381 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7382 0 : r.in.buffer = &blob;
7383 0 : r.in.offered = needed;
7384 0 : torture_assert_ntstatus_ok(tctx,
7385 : dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &r),
7386 : "failed to call GetPrinterDriver2");
7387 : }
7388 :
7389 0 : if (result_p) {
7390 0 : *result_p = r.out.result;
7391 : }
7392 :
7393 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INVALID_LEVEL)) {
7394 0 : switch (r.in.level) {
7395 0 : case 101:
7396 : case 8:
7397 0 : torture_comment(tctx,
7398 : "level %d not implemented, not considering as an error\n",
7399 : r.in.level);
7400 0 : return true;
7401 0 : default:
7402 0 : break;
7403 : }
7404 : }
7405 :
7406 0 : torture_assert_werr_ok(tctx, r.out.result,
7407 : "failed to call GetPrinterDriver2");
7408 :
7409 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
7410 :
7411 0 : if (info_p) {
7412 0 : *info_p = *r.out.info;
7413 : }
7414 :
7415 0 : return true;
7416 : }
7417 :
7418 0 : static bool test_GetPrinterDriver2(struct torture_context *tctx,
7419 : struct dcerpc_binding_handle *b,
7420 : struct policy_handle *handle,
7421 : const char *driver_name,
7422 : const char *architecture)
7423 : {
7424 0 : uint16_t levels[] = {1, 2, 3, 4, 5, 6, 8, 101 };
7425 0 : int i;
7426 :
7427 :
7428 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
7429 :
7430 0 : torture_assert(tctx,
7431 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, architecture, levels[i], 3, 0, NULL, NULL),
7432 : "");
7433 : }
7434 :
7435 0 : return true;
7436 : }
7437 :
7438 4 : static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
7439 : void *private_data)
7440 : {
7441 0 : struct test_spoolss_context *ctx =
7442 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
7443 4 : uint16_t levels[] = {1, 2, 3, 4, 5, 6};
7444 0 : int i;
7445 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
7446 4 : struct dcerpc_binding_handle *b = p->binding_handle;
7447 4 : const char *server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
7448 :
7449 4 : for (i=0;i<ARRAY_SIZE(levels);i++) {
7450 :
7451 0 : uint32_t count;
7452 0 : union spoolss_DriverInfo *info;
7453 :
7454 4 : torture_assert(tctx,
7455 : test_EnumPrinterDrivers_args(tctx, b, server_name, ctx->environment, levels[i], &count, &info),
7456 : "failed to enumerate drivers");
7457 :
7458 4 : if (!info) {
7459 4 : torture_comment(tctx, "No printer drivers returned\n");
7460 4 : break;
7461 : }
7462 : }
7463 :
7464 4 : return true;
7465 : }
7466 :
7467 16 : static bool test_DeletePrinter(struct torture_context *tctx,
7468 : struct dcerpc_binding_handle *b,
7469 : struct policy_handle *handle)
7470 : {
7471 0 : struct spoolss_DeletePrinter r;
7472 :
7473 16 : torture_comment(tctx, "Testing DeletePrinter\n");
7474 :
7475 16 : r.in.handle = handle;
7476 :
7477 16 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter_r(b, tctx, &r),
7478 : "failed to delete printer");
7479 16 : torture_assert_werr_ok(tctx, r.out.result,
7480 : "failed to delete printer");
7481 :
7482 16 : return true;
7483 : }
7484 :
7485 24 : static bool test_EnumPrinters_findname(struct torture_context *tctx,
7486 : struct dcerpc_binding_handle *b,
7487 : uint32_t flags,
7488 : uint32_t level,
7489 : const char *name,
7490 : bool *found)
7491 : {
7492 0 : struct spoolss_EnumPrinters e;
7493 0 : uint32_t count;
7494 0 : union spoolss_PrinterInfo *info;
7495 0 : uint32_t needed;
7496 0 : int i;
7497 :
7498 24 : *found = false;
7499 :
7500 24 : e.in.flags = flags;
7501 24 : e.in.server = NULL;
7502 24 : e.in.level = level;
7503 24 : e.in.buffer = NULL;
7504 24 : e.in.offered = 0;
7505 24 : e.out.count = &count;
7506 24 : e.out.info = &info;
7507 24 : e.out.needed = &needed;
7508 :
7509 24 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e),
7510 : "failed to enum printers");
7511 :
7512 24 : if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) {
7513 24 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7514 24 : e.in.buffer = &blob;
7515 24 : e.in.offered = needed;
7516 :
7517 24 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e),
7518 : "failed to enum printers");
7519 : }
7520 :
7521 24 : torture_assert_werr_ok(tctx, e.out.result,
7522 : "failed to enum printers");
7523 :
7524 152 : for (i=0; i < count; i++) {
7525 :
7526 152 : const char *current = NULL;
7527 0 : const char *q;
7528 :
7529 152 : switch (level) {
7530 152 : case 1:
7531 152 : current = info[i].info1.name;
7532 152 : break;
7533 : }
7534 :
7535 152 : if (strequal(current, name)) {
7536 24 : *found = true;
7537 24 : break;
7538 : }
7539 :
7540 128 : q = strrchr(current, '\\');
7541 128 : if (q) {
7542 0 : if (!e.in.server) {
7543 0 : torture_warning(tctx,
7544 : "server returns printername %s incl. servername although we did not set servername", current);
7545 : }
7546 0 : q++;
7547 0 : if (strequal(q, name)) {
7548 0 : *found = true;
7549 0 : break;
7550 : }
7551 : }
7552 : }
7553 :
7554 24 : return true;
7555 : }
7556 :
7557 0 : static bool test_AddPrinter_wellknown(struct torture_context *tctx,
7558 : struct dcerpc_pipe *p,
7559 : const char *printername,
7560 : bool ex)
7561 : {
7562 0 : WERROR result;
7563 0 : struct spoolss_AddPrinter r;
7564 0 : struct spoolss_AddPrinterEx rex;
7565 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
7566 0 : struct spoolss_SetPrinterInfo1 info1;
7567 0 : struct spoolss_DevmodeContainer devmode_ctr;
7568 0 : struct sec_desc_buf secdesc_ctr;
7569 0 : struct spoolss_UserLevelCtr userlevel_ctr;
7570 0 : struct policy_handle handle;
7571 0 : bool found = false;
7572 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7573 :
7574 0 : ZERO_STRUCT(devmode_ctr);
7575 0 : ZERO_STRUCT(secdesc_ctr);
7576 0 : ZERO_STRUCT(userlevel_ctr);
7577 0 : ZERO_STRUCT(info1);
7578 :
7579 0 : torture_comment(tctx, "Testing AddPrinter%s(%s) level 1\n",
7580 : ex ? "Ex":"", printername);
7581 :
7582 : /* try to add printer to wellknown printer list (level 1) */
7583 :
7584 0 : userlevel_ctr.level = 1;
7585 :
7586 0 : info_ctr.info.info1 = &info1;
7587 0 : info_ctr.level = 1;
7588 :
7589 0 : rex.in.server = NULL;
7590 0 : rex.in.info_ctr = &info_ctr;
7591 0 : rex.in.devmode_ctr = &devmode_ctr;
7592 0 : rex.in.secdesc_ctr = &secdesc_ctr;
7593 0 : rex.in.userlevel_ctr = &userlevel_ctr;
7594 0 : rex.out.handle = &handle;
7595 :
7596 0 : r.in.server = NULL;
7597 0 : r.in.info_ctr = &info_ctr;
7598 0 : r.in.devmode_ctr = &devmode_ctr;
7599 0 : r.in.secdesc_ctr = &secdesc_ctr;
7600 0 : r.out.handle = &handle;
7601 :
7602 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7603 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7604 : "failed to add printer");
7605 0 : result = ex ? rex.out.result : r.out.result;
7606 0 : torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
7607 : "unexpected result code");
7608 :
7609 0 : info1.name = printername;
7610 0 : info1.flags = PRINTER_ATTRIBUTE_SHARED;
7611 :
7612 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7613 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7614 : "failed to add printer");
7615 0 : result = ex ? rex.out.result : r.out.result;
7616 0 : torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
7617 : "unexpected result code");
7618 :
7619 : /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
7620 : better do a real check to see the printer is really there */
7621 :
7622 0 : torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
7623 : PRINTER_ENUM_NETWORK, 1,
7624 : printername,
7625 : &found),
7626 : "failed to enum printers");
7627 :
7628 0 : torture_assert(tctx, found, "failed to find newly added printer");
7629 :
7630 0 : info1.flags = 0;
7631 :
7632 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7633 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7634 : "failed to add printer");
7635 0 : result = ex ? rex.out.result : r.out.result;
7636 0 : torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
7637 : "unexpected result code");
7638 :
7639 : /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
7640 : better do a real check to see the printer has really been removed
7641 : from the well known printer list */
7642 :
7643 0 : found = false;
7644 :
7645 0 : torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
7646 : PRINTER_ENUM_NETWORK, 1,
7647 : printername,
7648 : &found),
7649 : "failed to enum printers");
7650 : #if 0
7651 : torture_assert(tctx, !found, "printer still in well known printer list");
7652 : #endif
7653 0 : return true;
7654 : }
7655 :
7656 16 : static bool test_AddPrinter_normal(struct torture_context *tctx,
7657 : struct dcerpc_pipe *p,
7658 : struct policy_handle *handle_p,
7659 : const char *printername,
7660 : const char *drivername,
7661 : const char *portname,
7662 : struct spoolss_DeviceMode *devmode,
7663 : bool ex)
7664 : {
7665 0 : WERROR result;
7666 0 : struct spoolss_AddPrinter r;
7667 0 : struct spoolss_AddPrinterEx rex;
7668 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
7669 0 : struct spoolss_SetPrinterInfo2 info2;
7670 0 : struct spoolss_DevmodeContainer devmode_ctr;
7671 0 : struct sec_desc_buf secdesc_ctr;
7672 0 : struct spoolss_UserLevelCtr userlevel_ctr;
7673 0 : struct policy_handle handle;
7674 16 : bool found = false;
7675 16 : bool existing_printer_deleted = false;
7676 16 : struct dcerpc_binding_handle *b = p->binding_handle;
7677 :
7678 16 : ZERO_STRUCT(devmode_ctr);
7679 16 : ZERO_STRUCT(secdesc_ctr);
7680 16 : ZERO_STRUCT(userlevel_ctr);
7681 :
7682 16 : torture_comment(tctx, "Testing AddPrinter%s(%s) level 2\n",
7683 : ex ? "Ex":"", printername);
7684 :
7685 16 : devmode_ctr.devmode = devmode;
7686 :
7687 16 : userlevel_ctr.level = 1;
7688 :
7689 16 : rex.in.server = NULL;
7690 16 : rex.in.info_ctr = &info_ctr;
7691 16 : rex.in.devmode_ctr = &devmode_ctr;
7692 16 : rex.in.secdesc_ctr = &secdesc_ctr;
7693 16 : rex.in.userlevel_ctr = &userlevel_ctr;
7694 16 : rex.out.handle = &handle;
7695 :
7696 16 : r.in.server = NULL;
7697 16 : r.in.info_ctr = &info_ctr;
7698 16 : r.in.devmode_ctr = &devmode_ctr;
7699 16 : r.in.secdesc_ctr = &secdesc_ctr;
7700 16 : r.out.handle = &handle;
7701 :
7702 16 : again:
7703 :
7704 : /* try to add printer to printer list (level 2) */
7705 :
7706 16 : ZERO_STRUCT(info2);
7707 :
7708 16 : info_ctr.info.info2 = &info2;
7709 16 : info_ctr.level = 2;
7710 :
7711 16 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7712 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7713 : "failed to add printer");
7714 16 : result = ex ? rex.out.result : r.out.result;
7715 16 : torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
7716 : "unexpected result code");
7717 :
7718 16 : info2.printername = printername;
7719 :
7720 16 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7721 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7722 : "failed to add printer");
7723 16 : result = ex ? rex.out.result : r.out.result;
7724 :
7725 16 : if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) {
7726 0 : struct policy_handle printer_handle;
7727 :
7728 0 : if (existing_printer_deleted) {
7729 0 : torture_fail(tctx, "already deleted printer still existing?");
7730 : }
7731 :
7732 0 : torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, NULL, &printer_handle),
7733 : "failed to open printer handle");
7734 :
7735 0 : torture_assert(tctx, test_DeletePrinter(tctx, b, &printer_handle),
7736 : "failed to delete printer");
7737 :
7738 0 : torture_assert(tctx, test_ClosePrinter(tctx, b, &printer_handle),
7739 : "failed to close server handle");
7740 :
7741 0 : existing_printer_deleted = true;
7742 :
7743 0 : goto again;
7744 : }
7745 :
7746 16 : torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT,
7747 : "unexpected result code");
7748 :
7749 16 : info2.portname = portname;
7750 :
7751 16 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7752 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7753 : "failed to add printer");
7754 16 : result = ex ? rex.out.result : r.out.result;
7755 16 : torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER,
7756 : "unexpected result code");
7757 :
7758 16 : info2.drivername = drivername;
7759 :
7760 16 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7761 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7762 : "failed to add printer");
7763 16 : result = ex ? rex.out.result : r.out.result;
7764 :
7765 : /* w2k8r2 allows one to add printer w/o defining printprocessor */
7766 :
7767 16 : if (!W_ERROR_IS_OK(result)) {
7768 16 : torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR,
7769 : "unexpected result code");
7770 :
7771 16 : info2.printprocessor = "winprint";
7772 :
7773 16 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7774 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7775 : "failed to add printer");
7776 16 : result = ex ? rex.out.result : r.out.result;
7777 16 : torture_assert_werr_ok(tctx, result,
7778 : "failed to add printer");
7779 : }
7780 :
7781 16 : *handle_p = handle;
7782 :
7783 : /* we are paranoid, really check if the printer is there now */
7784 :
7785 16 : torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
7786 : PRINTER_ENUM_LOCAL, 1,
7787 : printername,
7788 : &found),
7789 : "failed to enum printers");
7790 16 : torture_assert(tctx, found, "failed to find newly added printer");
7791 :
7792 16 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7793 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7794 : "failed to add printer");
7795 16 : result = ex ? rex.out.result : r.out.result;
7796 16 : torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
7797 : "unexpected result code");
7798 :
7799 16 : return true;
7800 : }
7801 :
7802 8 : static bool test_printer_info(struct torture_context *tctx,
7803 : void *private_data)
7804 : {
7805 0 : struct torture_printer_context *t =
7806 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7807 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
7808 8 : struct dcerpc_binding_handle *b = p->binding_handle;
7809 :
7810 8 : bool ret = true;
7811 :
7812 8 : if (torture_setting_bool(tctx, "samba3", false)) {
7813 8 : torture_skip(tctx, "skipping printer info cross tests against samba 3");
7814 : }
7815 :
7816 0 : if (!test_PrinterInfo(tctx, b, &t->handle)) {
7817 0 : ret = false;
7818 : }
7819 :
7820 0 : if (!test_SetPrinter_errors(tctx, b, &t->handle)) {
7821 0 : ret = false;
7822 : }
7823 :
7824 0 : return ret;
7825 : }
7826 :
7827 160 : static bool test_EnumPrinterKey(struct torture_context *tctx,
7828 : struct dcerpc_binding_handle *b,
7829 : struct policy_handle *handle,
7830 : const char *key_name,
7831 : const char ***array)
7832 : {
7833 0 : struct spoolss_EnumPrinterKey r;
7834 160 : uint32_t needed = 0;
7835 0 : union spoolss_KeyNames key_buffer;
7836 160 : int32_t offered[] = { 0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5, 256, 512, 1024, 2048 };
7837 0 : uint32_t _ndr_size;
7838 0 : int i;
7839 :
7840 160 : r.in.handle = handle;
7841 160 : r.in.key_name = key_name;
7842 160 : r.out.key_buffer = &key_buffer;
7843 160 : r.out.needed = &needed;
7844 160 : r.out._ndr_size = &_ndr_size;
7845 :
7846 2560 : for (i=0; i < ARRAY_SIZE(offered); i++) {
7847 :
7848 2400 : if (offered[i] < 0 && needed) {
7849 800 : if (needed <= 4) {
7850 340 : continue;
7851 : }
7852 460 : r.in.offered = needed + offered[i];
7853 : } else {
7854 1600 : r.in.offered = offered[i];
7855 : }
7856 :
7857 2060 : ZERO_STRUCT(key_buffer);
7858 :
7859 2060 : torture_comment(tctx, "Testing EnumPrinterKey(%s) with %d offered\n", r.in.key_name, r.in.offered);
7860 :
7861 2060 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &r),
7862 : "failed to call EnumPrinterKey");
7863 2060 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
7864 :
7865 1284 : torture_assert(tctx, (_ndr_size == r.in.offered/2),
7866 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7867 : _ndr_size, r.in.offered/2));
7868 :
7869 1284 : r.in.offered = needed;
7870 1284 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &r),
7871 : "failed to call EnumPrinterKey");
7872 : }
7873 :
7874 2060 : if (offered[i] > 0) {
7875 1440 : torture_assert_werr_ok(tctx, r.out.result,
7876 : "failed to call EnumPrinterKey");
7877 : }
7878 :
7879 2060 : torture_assert(tctx, (_ndr_size == r.in.offered/2),
7880 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7881 : _ndr_size, r.in.offered/2));
7882 :
7883 2060 : torture_assert(tctx, (*r.out.needed <= r.in.offered),
7884 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= offered %d", *r.out.needed, r.in.offered));
7885 :
7886 2060 : torture_assert(tctx, (*r.out.needed <= _ndr_size * 2),
7887 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2", *r.out.needed, _ndr_size));
7888 :
7889 2060 : if (key_buffer.string_array) {
7890 2060 : uint32_t calc_needed = 0;
7891 : int s;
7892 4040 : for (s=0; key_buffer.string_array[s]; s++) {
7893 1980 : calc_needed += strlen_m_term(key_buffer.string_array[s])*2;
7894 : }
7895 2060 : if (!key_buffer.string_array[0]) {
7896 680 : calc_needed += 2;
7897 : }
7898 2060 : calc_needed += 2;
7899 :
7900 2060 : torture_assert_int_equal(tctx, *r.out.needed, calc_needed,
7901 : "EnumPrinterKey unexpected size");
7902 : }
7903 : }
7904 :
7905 160 : if (array) {
7906 92 : *array = key_buffer.string_array;
7907 : }
7908 :
7909 160 : return true;
7910 : }
7911 :
7912 28 : bool test_printer_all_keys(struct torture_context *tctx,
7913 : struct dcerpc_binding_handle *b,
7914 : struct policy_handle *handle)
7915 : {
7916 28 : const char **key_array = NULL;
7917 0 : int i;
7918 :
7919 28 : torture_comment(tctx, "Testing Printer Keys\n");
7920 :
7921 28 : torture_assert(tctx, test_EnumPrinterKey(tctx, b, handle, "", &key_array),
7922 : "failed to call test_EnumPrinterKey");
7923 :
7924 96 : for (i=0; key_array && key_array[i]; i++) {
7925 68 : torture_assert(tctx, test_EnumPrinterKey(tctx, b, handle, key_array[i], NULL),
7926 : "failed to call test_EnumPrinterKey");
7927 : }
7928 96 : for (i=0; key_array && key_array[i]; i++) {
7929 68 : torture_assert(tctx, test_EnumPrinterDataEx(tctx, b, handle, key_array[i], NULL, NULL),
7930 : "failed to call test_EnumPrinterDataEx");
7931 : }
7932 :
7933 28 : torture_comment(tctx, "Printer Keys test succeeded\n\n");
7934 :
7935 28 : return true;
7936 : }
7937 :
7938 8 : static bool test_openprinter_wrap(struct torture_context *tctx,
7939 : void *private_data)
7940 : {
7941 0 : struct torture_printer_context *t =
7942 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7943 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
7944 8 : struct dcerpc_binding_handle *b = p->binding_handle;
7945 8 : const char *printername = t->info2.printername;
7946 :
7947 8 : return test_openprinter(tctx, b, printername);
7948 : }
7949 :
7950 8 : static bool test_csetprinter(struct torture_context *tctx,
7951 : void *private_data)
7952 : {
7953 0 : struct torture_printer_context *t =
7954 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7955 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
7956 :
7957 8 : const char *printername = talloc_asprintf(tctx, "%s2", t->info2.printername);
7958 8 : const char *drivername = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
7959 8 : const char *portname = t->info2.portname;
7960 :
7961 0 : union spoolss_PrinterInfo info;
7962 0 : struct policy_handle new_handle, new_handle2;
7963 8 : struct dcerpc_binding_handle *b = p->binding_handle;
7964 :
7965 8 : torture_comment(tctx, "Testing c_setprinter\n");
7966 :
7967 8 : torture_assert(tctx,
7968 : test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
7969 : "failed to get level 0 printer info");
7970 8 : torture_comment(tctx, "csetprinter on initial printer handle: %d\n",
7971 : info.info0.c_setprinter);
7972 :
7973 : /* check if c_setprinter on 1st handle increases after a printer has
7974 : * been added */
7975 :
7976 8 : torture_assert(tctx,
7977 : test_AddPrinter_normal(tctx, p, &new_handle, printername, drivername, portname, NULL, false),
7978 : "failed to add new printer");
7979 8 : torture_assert(tctx,
7980 : test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
7981 : "failed to get level 0 printer info");
7982 8 : torture_comment(tctx, "csetprinter on initial printer handle (after add): %d\n",
7983 : info.info0.c_setprinter);
7984 :
7985 : /* check if c_setprinter on new handle increases after a printer has
7986 : * been added */
7987 :
7988 8 : torture_assert(tctx,
7989 : test_GetPrinter_level(tctx, b, &new_handle, 0, &info),
7990 : "failed to get level 0 printer info");
7991 8 : torture_comment(tctx, "csetprinter on created handle: %d\n",
7992 : info.info0.c_setprinter);
7993 :
7994 : /* open the new printer and check if c_setprinter increases */
7995 :
7996 8 : torture_assert(tctx,
7997 : call_OpenPrinterEx(tctx, p, printername, NULL, &new_handle2),
7998 : "failed to open created printer");
7999 8 : torture_assert(tctx,
8000 : test_GetPrinter_level(tctx, b, &new_handle2, 0, &info),
8001 : "failed to get level 0 printer info");
8002 8 : torture_comment(tctx, "csetprinter on new handle (after openprinter): %d\n",
8003 : info.info0.c_setprinter);
8004 :
8005 : /* cleanup */
8006 :
8007 8 : torture_assert(tctx,
8008 : test_ClosePrinter(tctx, b, &new_handle2),
8009 : "failed to close printer");
8010 8 : torture_assert(tctx,
8011 : test_DeletePrinter(tctx, b, &new_handle),
8012 : "failed to delete new printer");
8013 :
8014 8 : return true;
8015 : }
8016 :
8017 8 : static bool compose_local_driver_directory(struct torture_context *tctx,
8018 : const char *environment,
8019 : const char *local_dir,
8020 : const char **path)
8021 : {
8022 0 : char *p;
8023 :
8024 8 : p = strrchr(local_dir, '/');
8025 8 : if (!p) {
8026 0 : return NULL;
8027 : }
8028 8 : p++;
8029 :
8030 8 : if (strequal(environment, SPOOLSS_ARCHITECTURE_x64)) {
8031 8 : if (!strequal(p, "x64")) {
8032 8 : *path = talloc_asprintf(tctx, "%s/x64", local_dir);
8033 : }
8034 0 : } else if (strequal(environment, SPOOLSS_ARCHITECTURE_NT_X86)) {
8035 0 : if (!strequal(p, "i386")) {
8036 0 : *path = talloc_asprintf(tctx, "%s/i386", local_dir);
8037 : }
8038 : } else {
8039 : torture_assert(tctx, "unknown environment: '%s'\n", environment);
8040 : }
8041 :
8042 8 : return true;
8043 : }
8044 :
8045 : #if 0
8046 : static struct spoolss_DeviceMode *torture_devicemode(TALLOC_CTX *mem_ctx,
8047 : const char *devicename)
8048 : {
8049 : struct spoolss_DeviceMode *r;
8050 :
8051 : r = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
8052 : if (r == NULL) {
8053 : return NULL;
8054 : }
8055 :
8056 : r->devicename = talloc_strdup(r, devicename);
8057 : r->specversion = DMSPEC_NT4_AND_ABOVE;
8058 : r->driverversion = 0x0600;
8059 : r->size = 0x00dc;
8060 : r->__driverextra_length = 0;
8061 : r->fields = DEVMODE_FORMNAME |
8062 : DEVMODE_TTOPTION |
8063 : DEVMODE_PRINTQUALITY |
8064 : DEVMODE_DEFAULTSOURCE |
8065 : DEVMODE_COPIES |
8066 : DEVMODE_SCALE |
8067 : DEVMODE_PAPERSIZE |
8068 : DEVMODE_ORIENTATION;
8069 : r->orientation = DMORIENT_PORTRAIT;
8070 : r->papersize = DMPAPER_LETTER;
8071 : r->paperlength = 0;
8072 : r->paperwidth = 0;
8073 : r->scale = 100;
8074 : r->copies = 55;
8075 : r->defaultsource = DMBIN_FORMSOURCE;
8076 : r->printquality = DMRES_HIGH;
8077 : r->color = DMRES_MONOCHROME;
8078 : r->duplex = DMDUP_SIMPLEX;
8079 : r->yresolution = 0;
8080 : r->ttoption = DMTT_SUBDEV;
8081 : r->collate = DMCOLLATE_FALSE;
8082 : r->formname = talloc_strdup(r, "Letter");
8083 :
8084 : return r;
8085 : }
8086 : #endif
8087 :
8088 4 : static bool test_architecture_buffer(struct torture_context *tctx,
8089 : void *private_data)
8090 : {
8091 0 : struct test_spoolss_context *ctx =
8092 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8093 :
8094 0 : struct spoolss_OpenPrinterEx r;
8095 0 : struct spoolss_UserLevel1 u1;
8096 0 : struct policy_handle handle;
8097 4 : uint32_t architectures[] = {
8098 : PROCESSOR_ARCHITECTURE_INTEL,
8099 : PROCESSOR_ARCHITECTURE_IA64,
8100 : PROCESSOR_ARCHITECTURE_AMD64
8101 : };
8102 0 : uint32_t needed[3];
8103 0 : int i;
8104 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8105 4 : struct dcerpc_binding_handle *b = p->binding_handle;
8106 :
8107 16 : for (i=0; i < ARRAY_SIZE(architectures); i++) {
8108 :
8109 12 : torture_comment(tctx, "Testing OpenPrinterEx with architecture %d\n", architectures[i]);
8110 :
8111 12 : u1.size = 0;
8112 12 : u1.client = NULL;
8113 12 : u1.user = NULL;
8114 12 : u1.build = 0;
8115 12 : u1.major = 3;
8116 12 : u1.minor = 0;
8117 12 : u1.processor = architectures[i];
8118 :
8119 12 : r.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8120 12 : r.in.datatype = NULL;
8121 12 : r.in.devmode_ctr.devmode= NULL;
8122 12 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8123 12 : r.in.userlevel_ctr.level = 1;
8124 12 : r.in.userlevel_ctr.user_info.level1 = &u1;
8125 12 : r.out.handle = &handle;
8126 :
8127 12 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r), "");
8128 12 : torture_assert_werr_ok(tctx, r.out.result, "");
8129 :
8130 : {
8131 0 : struct spoolss_EnumPrinters e;
8132 0 : uint32_t count;
8133 0 : union spoolss_PrinterInfo *info;
8134 :
8135 12 : e.in.flags = PRINTER_ENUM_LOCAL;
8136 12 : e.in.server = NULL;
8137 12 : e.in.level = 2;
8138 12 : e.in.buffer = NULL;
8139 12 : e.in.offered = 0;
8140 12 : e.out.count = &count;
8141 12 : e.out.info = &info;
8142 12 : e.out.needed = &needed[i];
8143 :
8144 12 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e), "");
8145 : #if 0
8146 : torture_comment(tctx, "needed was %d\n", needed[i]);
8147 : #endif
8148 : }
8149 :
8150 12 : torture_assert(tctx, test_ClosePrinter(tctx, b, &handle), "");
8151 : }
8152 :
8153 12 : for (i=1; i < ARRAY_SIZE(architectures); i++) {
8154 8 : if (needed[i-1] != needed[i]) {
8155 0 : torture_fail(tctx,
8156 : talloc_asprintf(tctx, "needed size %d for architecture %d != needed size %d for architecture %d\n",
8157 : needed[i-1], architectures[i-1], needed[i], architectures[i]));
8158 : }
8159 : }
8160 :
8161 4 : return true;
8162 : }
8163 :
8164 8 : static bool test_get_core_printer_drivers_arch_guid(struct torture_context *tctx,
8165 : struct dcerpc_pipe *p,
8166 : const char *architecture,
8167 : const char *guid_str,
8168 : const char **package_id)
8169 : {
8170 0 : struct spoolss_GetCorePrinterDrivers r;
8171 0 : struct spoolss_CorePrinterDriver core_printer_drivers;
8172 8 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 2);
8173 0 : const char **s;
8174 8 : struct dcerpc_binding_handle *b = p->binding_handle;
8175 0 : struct GUID guid;
8176 :
8177 8 : s = talloc_zero_array(tctx, const char *, 2);
8178 :
8179 8 : r.in.servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8180 8 : r.in.architecture = "foobar";
8181 8 : r.in.core_driver_size = 0;
8182 8 : r.in.core_driver_dependencies = (uint16_t *)blob.data;
8183 8 : r.in.core_printer_driver_count = 0;
8184 8 : r.out.core_printer_drivers = &core_printer_drivers;
8185 :
8186 8 : torture_assert_ntstatus_ok(tctx,
8187 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8188 : "spoolss_GetCorePrinterDrivers failed");
8189 0 : torture_assert_hresult_equal(tctx, r.out.result, HRES_E_INVALIDARG,
8190 : "spoolss_GetCorePrinterDrivers failed");
8191 :
8192 0 : guid = GUID_random();
8193 0 : s[0] = GUID_string2(tctx, &guid);
8194 :
8195 0 : torture_assert(tctx,
8196 : push_reg_multi_sz(tctx, &blob, s),
8197 : "push_reg_multi_sz failed");
8198 :
8199 0 : r.in.core_driver_size = blob.length/2;
8200 0 : r.in.core_driver_dependencies = (uint16_t *)blob.data;
8201 0 : r.in.core_printer_driver_count = 1;
8202 0 : r.out.core_printer_drivers = talloc_zero_array(tctx, struct spoolss_CorePrinterDriver, r.in.core_printer_driver_count);
8203 :
8204 0 : torture_assert_ntstatus_ok(tctx,
8205 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8206 : "spoolss_GetCorePrinterDrivers failed");
8207 0 : torture_assert_werr_equal(tctx,
8208 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
8209 : "spoolss_GetCorePrinterDrivers failed");
8210 :
8211 0 : r.in.architecture = architecture;
8212 :
8213 0 : torture_assert_ntstatus_ok(tctx,
8214 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8215 : "spoolss_GetCorePrinterDrivers failed");
8216 0 : torture_assert_werr_equal(tctx,
8217 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_NOT_FOUND,
8218 : "spoolss_GetCorePrinterDrivers failed");
8219 :
8220 0 : s[0] = talloc_strdup(s, guid_str);
8221 :
8222 0 : torture_assert(tctx,
8223 : push_reg_multi_sz(tctx, &blob, s),
8224 : "push_reg_multi_sz failed");
8225 :
8226 0 : r.in.core_driver_size = blob.length/2;
8227 0 : r.in.core_driver_dependencies = (uint16_t *)blob.data;
8228 0 : r.in.core_printer_driver_count = 1;
8229 0 : r.out.core_printer_drivers = talloc_zero_array(tctx, struct spoolss_CorePrinterDriver, r.in.core_printer_driver_count);
8230 :
8231 0 : torture_assert_ntstatus_ok(tctx,
8232 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8233 : "spoolss_GetCorePrinterDrivers failed");
8234 0 : torture_assert_hresult_ok(tctx, r.out.result,
8235 : "spoolss_GetCorePrinterDrivers failed");
8236 :
8237 0 : if (package_id) {
8238 0 : *package_id = r.out.core_printer_drivers[0].szPackageID;
8239 : }
8240 :
8241 0 : return true;
8242 : }
8243 :
8244 4 : static bool test_get_core_printer_drivers(struct torture_context *tctx,
8245 : void *private_data)
8246 : {
8247 0 : struct test_spoolss_context *ctx =
8248 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8249 :
8250 4 : const char *architectures[] = {
8251 : SPOOLSS_ARCHITECTURE_NT_X86,
8252 : SPOOLSS_ARCHITECTURE_x64
8253 : };
8254 0 : int i;
8255 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8256 :
8257 4 : for (i=0; i < ARRAY_SIZE(architectures); i++) {
8258 :
8259 4 : torture_comment(tctx, "Testing GetCorePrinterDrivers(\"%s\",\"%s\")\n",
8260 : architectures[i],
8261 : SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV);
8262 :
8263 4 : torture_assert(tctx,
8264 : test_get_core_printer_drivers_arch_guid(tctx, p,
8265 : architectures[i],
8266 : SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV,
8267 : NULL),
8268 : "");
8269 : }
8270 :
8271 0 : return true;
8272 : }
8273 :
8274 4 : static bool test_get_printer_driver_package_path(struct torture_context *tctx,
8275 : void *private_data)
8276 : {
8277 0 : struct test_spoolss_context *ctx =
8278 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8279 :
8280 4 : const char *architectures[] = {
8281 : SPOOLSS_ARCHITECTURE_NT_X86,
8282 : SPOOLSS_ARCHITECTURE_x64
8283 : };
8284 0 : int i;
8285 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8286 4 : struct dcerpc_binding_handle *b = p->binding_handle;
8287 :
8288 4 : for (i=0; i < ARRAY_SIZE(architectures); i++) {
8289 0 : struct spoolss_GetPrinterDriverPackagePath r;
8290 4 : uint32_t required = 0;
8291 4 : const char *package_id = NULL;
8292 :
8293 4 : test_get_core_printer_drivers_arch_guid(tctx, p,
8294 : architectures[i],
8295 : SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV,
8296 : &package_id),
8297 :
8298 4 : torture_comment(tctx, "Testing GetPrinterDriverPackagePath(\"%s\",\"%s\")\n",
8299 : architectures[i], package_id);
8300 :
8301 4 : r.in.servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8302 4 : r.in.architecture = "foobar";
8303 4 : r.in.language = NULL;
8304 4 : r.in.package_id = "";
8305 4 : r.in.driver_package_cab_size = 0;
8306 4 : r.in.driver_package_cab = NULL;
8307 :
8308 4 : r.out.required = &required;
8309 4 : r.out.driver_package_cab = NULL;
8310 :
8311 4 : torture_assert_ntstatus_ok(tctx,
8312 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8313 : "spoolss_GetPrinterDriverPackagePath failed");
8314 0 : torture_assert_werr_equal(tctx,
8315 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
8316 : "spoolss_GetPrinterDriverPackagePath failed");
8317 :
8318 0 : r.in.architecture = architectures[i];
8319 :
8320 0 : torture_assert_ntstatus_ok(tctx,
8321 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8322 : "spoolss_GetPrinterDriverPackagePath failed");
8323 0 : torture_assert_werr_equal(tctx,
8324 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
8325 : "spoolss_GetPrinterDriverPackagePath failed");
8326 :
8327 0 : r.in.package_id = package_id;
8328 :
8329 0 : torture_assert_ntstatus_ok(tctx,
8330 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8331 : "spoolss_GetPrinterDriverPackagePath failed");
8332 0 : torture_assert_hresult_ok(tctx, r.out.result,
8333 : "spoolss_GetPrinterDriverPackagePath failed");
8334 :
8335 0 : r.in.driver_package_cab_size = required;
8336 0 : r.in.driver_package_cab = talloc_zero_array(tctx, char, required);
8337 0 : r.out.driver_package_cab = talloc_zero_array(tctx, char, required);
8338 :
8339 0 : torture_assert_ntstatus_ok(tctx,
8340 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8341 : "spoolss_GetPrinterDriverPackagePath failed");
8342 0 : torture_assert_hresult_ok(tctx, r.out.result,
8343 : "spoolss_GetPrinterDriverPackagePath failed");
8344 :
8345 0 : r.in.servername = NULL;
8346 :
8347 0 : torture_assert_ntstatus_ok(tctx,
8348 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8349 : "spoolss_GetPrinterDriverPackagePath failed");
8350 0 : torture_assert_werr_equal(tctx,
8351 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INSUFFICIENT_BUFFER,
8352 : "spoolss_GetPrinterDriverPackagePath failed");
8353 :
8354 0 : r.in.driver_package_cab_size = required;
8355 0 : r.in.driver_package_cab = talloc_zero_array(tctx, char, required);
8356 0 : r.out.driver_package_cab = talloc_zero_array(tctx, char, required);
8357 :
8358 0 : torture_assert_ntstatus_ok(tctx,
8359 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8360 : "spoolss_GetPrinterDriverPackagePath failed");
8361 0 : torture_assert_hresult_ok(tctx, r.out.result,
8362 : "spoolss_GetPrinterDriverPackagePath failed");
8363 :
8364 : }
8365 :
8366 0 : return true;
8367 : }
8368 :
8369 4 : static bool test_get_printer_printserverhandle(struct torture_context *tctx,
8370 : void *private_data)
8371 : {
8372 0 : struct test_spoolss_context *ctx =
8373 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8374 :
8375 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8376 4 : struct dcerpc_binding_handle *b = p->binding_handle;
8377 4 : uint32_t levels[] = {0, 1, 2, /* 3,*/ 4, 5, 6, 7, 8};
8378 0 : int i;
8379 :
8380 36 : for (i=0;i<ARRAY_SIZE(levels);i++) {
8381 :
8382 32 : torture_assert(tctx,
8383 : test_GetPrinter_level_exp(tctx, b, &ctx->server_handle,
8384 : levels[i], WERR_INVALID_LEVEL,
8385 : NULL),
8386 : "failed to call GetPrinter");
8387 : }
8388 :
8389 4 : torture_assert(tctx,
8390 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, NULL),
8391 : "failed to call GetPrinter");
8392 :
8393 4 : return true;
8394 : }
8395 :
8396 : #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
8397 :
8398 4 : static bool test_set_printer_printserverhandle(struct torture_context *tctx,
8399 : void *private_data)
8400 : {
8401 0 : struct test_spoolss_context *ctx =
8402 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8403 :
8404 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8405 4 : struct dcerpc_binding_handle *b = p->binding_handle;
8406 0 : union spoolss_PrinterInfo info;
8407 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
8408 0 : struct spoolss_SetPrinterInfo3 info3;
8409 0 : struct spoolss_DevmodeContainer devmode_ctr;
8410 0 : struct sec_desc_buf secdesc_ctr;
8411 0 : struct security_descriptor *sd;
8412 0 : struct security_ace *ace;
8413 0 : struct dom_sid sid;
8414 0 : int i;
8415 :
8416 4 : torture_assert(tctx,
8417 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, &info),
8418 : "failed to call GetPrinter");
8419 :
8420 4 : secdesc_ctr.sd = info.info3.secdesc;
8421 4 : secdesc_ctr.sd->owner_sid = NULL;
8422 4 : secdesc_ctr.sd->group_sid = NULL;
8423 :
8424 4 : sd = security_descriptor_copy(tctx, secdesc_ctr.sd);
8425 4 : if (sd == NULL) {
8426 0 : return false;
8427 : }
8428 :
8429 4 : ace = security_ace_create(tctx,
8430 : TEST_SID,
8431 : SEC_ACE_TYPE_ACCESS_ALLOWED,
8432 : SEC_STD_REQUIRED,
8433 : SEC_ACE_FLAG_CONTAINER_INHERIT);
8434 4 : torture_assert(tctx, ace, "failed to create ace");
8435 :
8436 4 : torture_assert_ntstatus_ok(tctx,
8437 : security_descriptor_dacl_add(sd, ace),
8438 : "failed to add ace");
8439 :
8440 4 : secdesc_ctr.sd = sd;
8441 :
8442 4 : info3.sec_desc_ptr = 0;
8443 :
8444 4 : info_ctr.level = 3;
8445 4 : info_ctr.info.info3 = &info3;
8446 :
8447 4 : ZERO_STRUCT(devmode_ctr);
8448 :
8449 4 : torture_assert(tctx,
8450 : test_SetPrinter(tctx, b, &ctx->server_handle, &info_ctr,
8451 : &devmode_ctr, &secdesc_ctr, 0),
8452 : "failed to call SetPrinter");
8453 :
8454 4 : torture_assert(tctx,
8455 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, &info),
8456 : "failed to call GetPrinter");
8457 :
8458 32 : for (i = 0; i < info.info3.secdesc->dacl->num_aces; i++) {
8459 32 : if (security_ace_equal(&info.info3.secdesc->dacl->aces[i], ace)) {
8460 4 : break;
8461 : }
8462 : }
8463 :
8464 4 : if (i == info.info3.secdesc->dacl->num_aces) {
8465 0 : torture_fail(tctx, "ace not present");
8466 : }
8467 :
8468 4 : torture_assert(tctx,
8469 : dom_sid_parse(TEST_SID, &sid),
8470 : "failed to parse sid");
8471 :
8472 4 : torture_assert_ntstatus_ok(tctx,
8473 : security_descriptor_dacl_del(info.info3.secdesc, &sid),
8474 : "failed to remove ace from sd");
8475 :
8476 4 : secdesc_ctr.sd = info.info3.secdesc;
8477 :
8478 4 : torture_assert(tctx,
8479 : test_SetPrinter(tctx, b, &ctx->server_handle, &info_ctr,
8480 : &devmode_ctr, &secdesc_ctr, 0),
8481 : "failed to call SetPrinter");
8482 :
8483 4 : torture_assert(tctx,
8484 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, &info),
8485 : "failed to call GetPrinter");
8486 :
8487 32 : for (i = 0; i < info.info3.secdesc->dacl->num_aces; i++) {
8488 28 : if (security_ace_equal(&info.info3.secdesc->dacl->aces[i], ace)) {
8489 0 : torture_fail(tctx, "ace still present");
8490 : }
8491 : }
8492 :
8493 4 : return true;
8494 : }
8495 :
8496 :
8497 4 : static bool test_PrintServer_Forms_Winreg(struct torture_context *tctx,
8498 : void *private_data)
8499 : {
8500 0 : struct test_spoolss_context *ctx =
8501 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8502 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8503 4 : struct dcerpc_binding_handle *b = p->binding_handle;
8504 :
8505 4 : return test_Forms_winreg(tctx, b, &ctx->server_handle, true, NULL);
8506 : }
8507 :
8508 4 : static bool test_PrintServer_Forms(struct torture_context *tctx,
8509 : void *private_data)
8510 : {
8511 0 : struct test_spoolss_context *ctx =
8512 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8513 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8514 4 : struct dcerpc_binding_handle *b = p->binding_handle;
8515 :
8516 4 : return test_Forms(tctx, b, &ctx->server_handle, true, NULL, NULL, NULL);
8517 : }
8518 :
8519 4 : static bool test_PrintServer_EnumForms(struct torture_context *tctx,
8520 : void *private_data)
8521 : {
8522 0 : struct test_spoolss_context *ctx =
8523 4 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8524 4 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8525 4 : struct dcerpc_binding_handle *b = p->binding_handle;
8526 :
8527 4 : return test_EnumForms_all(tctx, b, &ctx->server_handle, true);
8528 : }
8529 :
8530 4 : static bool torture_rpc_spoolss_setup_common(struct torture_context *tctx, struct test_spoolss_context *t)
8531 : {
8532 0 : NTSTATUS status;
8533 :
8534 4 : status = torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss);
8535 :
8536 4 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
8537 :
8538 4 : torture_assert(tctx,
8539 : test_OpenPrinter_server(tctx, t->spoolss_pipe, &t->server_handle),
8540 : "failed to open printserver");
8541 4 : torture_assert(tctx,
8542 : test_get_environment(tctx, t->spoolss_pipe->binding_handle, &t->server_handle, &t->environment),
8543 : "failed to get environment");
8544 :
8545 4 : return true;
8546 : }
8547 :
8548 4 : static bool torture_rpc_spoolss_setup(struct torture_context *tctx, void **data)
8549 : {
8550 0 : struct test_spoolss_context *t;
8551 :
8552 4 : *data = t = talloc_zero(tctx, struct test_spoolss_context);
8553 :
8554 4 : return torture_rpc_spoolss_setup_common(tctx, t);
8555 : }
8556 :
8557 4 : static bool torture_rpc_spoolss_teardown_common(struct torture_context *tctx, struct test_spoolss_context *t)
8558 : {
8559 4 : test_ClosePrinter(tctx, t->spoolss_pipe->binding_handle, &t->server_handle);
8560 :
8561 4 : return true;
8562 : }
8563 :
8564 4 : static bool torture_rpc_spoolss_teardown(struct torture_context *tctx, void *data)
8565 : {
8566 4 : struct test_spoolss_context *t = talloc_get_type(data, struct test_spoolss_context);
8567 0 : bool ret;
8568 :
8569 4 : ret = torture_rpc_spoolss_teardown_common(tctx, t);
8570 4 : talloc_free(t);
8571 :
8572 4 : return ret;
8573 : }
8574 :
8575 8 : static bool torture_rpc_spoolss_printer_setup_common(struct torture_context *tctx, struct torture_printer_context *t)
8576 : {
8577 0 : struct dcerpc_pipe *p;
8578 0 : struct dcerpc_binding_handle *b;
8579 0 : const char *server_name_slash;
8580 0 : const char *driver_name;
8581 0 : const char *printer_name;
8582 0 : const char *port_name;
8583 :
8584 8 : torture_assert_ntstatus_ok(tctx,
8585 : torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss),
8586 : "Error connecting to server");
8587 :
8588 8 : p = t->spoolss_pipe;
8589 8 : b = p->binding_handle;
8590 8 : server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8591 :
8592 8 : t->driver.info8.version = SPOOLSS_DRIVER_VERSION_200X;
8593 8 : t->driver.info8.driver_name = TORTURE_DRIVER;
8594 8 : t->driver.info8.driver_path = "pscript5.dll";
8595 8 : t->driver.info8.data_file = "cups6.ppd";
8596 8 : t->driver.info8.config_file = "ps5ui.dll";
8597 8 : t->driver.info8.help_file = "pscript.hlp";
8598 8 : t->driver.info8.default_datatype = "RAW";
8599 8 : t->driver.info8.dependent_files = talloc_zero(t, struct spoolss_StringArray);
8600 8 : t->driver.info8.dependent_files->string = talloc_zero_array(t, const char *, 8 + 1);
8601 8 : t->driver.info8.dependent_files->string[0] = "pscript5.dll";
8602 8 : t->driver.info8.dependent_files->string[1] = "cups6.ppd";
8603 8 : t->driver.info8.dependent_files->string[2] = "ps5ui.dll";
8604 8 : t->driver.info8.dependent_files->string[3] = "pscript.hlp";
8605 8 : t->driver.info8.dependent_files->string[4] = "pscript.ntf";
8606 8 : t->driver.info8.dependent_files->string[5] = "cups6.ini";
8607 8 : t->driver.info8.dependent_files->string[6] = "cupsps6.dll";
8608 8 : t->driver.info8.dependent_files->string[7] = "cupsui6.dll";
8609 :
8610 8 : t->driver.local.driver_directory= "/usr/share/cups/drivers";
8611 :
8612 8 : t->info2.portname = "LPT1:";
8613 :
8614 8 : printer_name = t->info2.printername;
8615 8 : port_name = t->info2.portname;
8616 :
8617 8 : torture_assert(tctx,
8618 : fillup_printserver_info(tctx, p, &t->driver),
8619 : "failed to fillup printserver info");
8620 :
8621 8 : t->driver.info8.architecture = talloc_strdup(t, t->driver.remote.environment);
8622 :
8623 8 : torture_assert(tctx,
8624 : compose_local_driver_directory(tctx, t->driver.remote.environment,
8625 : t->driver.local.driver_directory,
8626 : &t->driver.local.driver_directory),
8627 : "failed to compose local driver directory");
8628 :
8629 8 : t->info2.drivername = "Microsoft XPS Document Writer";
8630 :
8631 8 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, t->driver.remote.environment, 3, t->info2.drivername, NULL)) {
8632 0 : torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) is present on server\n",
8633 : t->info2.drivername, t->driver.remote.environment);
8634 0 : t->have_driver = true;
8635 0 : goto try_add;
8636 : }
8637 :
8638 8 : torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) does not exist on the server\n",
8639 : t->info2.drivername, t->driver.remote.environment);
8640 :
8641 8 : t->info2.drivername = "Microsoft XPS Document Writer v4";
8642 :
8643 8 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, t->driver.remote.environment, 3, t->info2.drivername, NULL)) {
8644 0 : torture_comment(tctx, "driver '%s' (architecture: %s, version: 4) is present on server\n",
8645 : t->info2.drivername, t->driver.remote.environment);
8646 0 : t->have_driver = true;
8647 0 : goto try_add;
8648 : }
8649 :
8650 8 : torture_comment(tctx, "trying to upload own driver\n");
8651 :
8652 8 : if (!directory_exist(t->driver.local.driver_directory)) {
8653 8 : torture_warning(tctx, "no local driver is available!");
8654 8 : t->have_driver = false;
8655 8 : goto try_add;
8656 : }
8657 :
8658 0 : torture_assert(tctx,
8659 : upload_printer_driver(tctx, dcerpc_server_name(p), &t->driver),
8660 : "failed to upload printer driver");
8661 :
8662 0 : torture_assert(tctx,
8663 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &t->driver.info8, 0, false, NULL),
8664 : "failed to add driver");
8665 :
8666 0 : t->added_driver = true;
8667 0 : t->have_driver = true;
8668 :
8669 8 : try_add:
8670 8 : driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
8671 :
8672 8 : if (t->wellknown) {
8673 0 : torture_assert(tctx,
8674 : test_AddPrinter_wellknown(tctx, p, printer_name, t->ex),
8675 : "failed to add wellknown printer");
8676 : } else {
8677 8 : torture_assert(tctx,
8678 : test_AddPrinter_normal(tctx, p, &t->handle, printer_name, driver_name, port_name, t->devmode, t->ex),
8679 : "failed to add printer");
8680 : }
8681 :
8682 8 : return true;
8683 : }
8684 :
8685 4 : static bool torture_rpc_spoolss_printer_setup(struct torture_context *tctx, void **data)
8686 : {
8687 0 : struct torture_printer_context *t;
8688 :
8689 4 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8690 :
8691 4 : t->ex = false;
8692 4 : t->wellknown = false;
8693 4 : t->info2.printername = TORTURE_PRINTER;
8694 4 : t->devmode = NULL;
8695 :
8696 4 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8697 : }
8698 :
8699 4 : static bool torture_rpc_spoolss_printerex_setup(struct torture_context *tctx, void **data)
8700 : {
8701 0 : struct torture_printer_context *t;
8702 :
8703 4 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8704 :
8705 4 : t->ex = true;
8706 4 : t->wellknown = false;
8707 4 : t->info2.printername = TORTURE_PRINTER_EX;
8708 4 : t->devmode = NULL;
8709 :
8710 4 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8711 : }
8712 :
8713 4 : static bool torture_rpc_spoolss_printerwkn_setup(struct torture_context *tctx, void **data)
8714 : {
8715 0 : struct torture_printer_context *t;
8716 :
8717 4 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8718 :
8719 4 : t->ex = false;
8720 4 : t->wellknown = true;
8721 4 : t->info2.printername = TORTURE_WELLKNOWN_PRINTER;
8722 4 : t->devmode = NULL;
8723 :
8724 : /* FIXME */
8725 4 : if (t->wellknown) {
8726 4 : torture_skip(tctx, "skipping AddPrinter level 1");
8727 : }
8728 :
8729 0 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8730 : }
8731 :
8732 4 : static bool torture_rpc_spoolss_printerexwkn_setup(struct torture_context *tctx, void **data)
8733 : {
8734 0 : struct torture_printer_context *t;
8735 :
8736 4 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8737 :
8738 4 : t->ex = true;
8739 4 : t->wellknown = true;
8740 4 : t->info2.printername = TORTURE_WELLKNOWN_PRINTER_EX;
8741 4 : t->devmode = NULL;
8742 :
8743 : /* FIXME */
8744 4 : if (t->wellknown) {
8745 4 : torture_skip(tctx, "skipping AddPrinterEx level 1");
8746 : }
8747 :
8748 0 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8749 : }
8750 :
8751 : #if 0
8752 : static bool torture_rpc_spoolss_printerdm_setup(struct torture_context *tctx, void **data)
8753 : {
8754 : struct torture_printer_context *t;
8755 :
8756 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8757 :
8758 : t->ex = true;
8759 : t->wellknown = false;
8760 : t->info2.printername = TORTURE_PRINTER_EX;
8761 : t->devmode = torture_devicemode(t, TORTURE_PRINTER_EX);
8762 :
8763 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8764 : }
8765 : #endif
8766 :
8767 : static bool test_DeletePrinterDriverEx_exp(struct torture_context *tctx,
8768 : struct dcerpc_binding_handle *b,
8769 : const char *server,
8770 : const char *driver,
8771 : const char *environment,
8772 : uint32_t delete_flags,
8773 : uint32_t version,
8774 : WERROR expected_result);
8775 :
8776 16 : static bool torture_rpc_spoolss_printer_teardown_common(struct torture_context *tctx, struct torture_printer_context *t)
8777 : {
8778 16 : bool found = false;
8779 16 : struct dcerpc_pipe *p = t->spoolss_pipe;
8780 16 : struct dcerpc_binding_handle *b = NULL;
8781 0 : const char *server_name_slash;
8782 16 : bool ok = true;
8783 :
8784 16 : if (p == NULL) {
8785 8 : return true;
8786 : }
8787 8 : b = p->binding_handle;
8788 :
8789 8 : server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8790 :
8791 8 : if (!t->wellknown) {
8792 8 : const char *printer_name = t->info2.printername;
8793 :
8794 8 : torture_assert_goto(tctx,
8795 : test_DeletePrinter(tctx, b, &t->handle),
8796 : ok,
8797 : remove_driver,
8798 : "failed to delete printer");
8799 :
8800 8 : torture_assert_goto(tctx,
8801 : test_EnumPrinters_findname(tctx, b, PRINTER_ENUM_LOCAL, 1,
8802 : printer_name, &found),
8803 : ok,
8804 : remove_driver,
8805 : "failed to enumerate printers");
8806 :
8807 8 : torture_assert_goto(tctx,
8808 : !found,
8809 : ok,
8810 : remove_driver,
8811 : "deleted printer still there");
8812 : }
8813 :
8814 :
8815 0 : remove_driver:
8816 8 : if (t->added_driver) {
8817 0 : ok = remove_printer_driver(tctx,
8818 : dcerpc_server_name(p),
8819 : &t->driver);
8820 0 : if (!ok) {
8821 0 : torture_warning(tctx,
8822 : "failed to remove printer driver\n");
8823 : }
8824 :
8825 0 : ok = test_DeletePrinterDriverEx_exp(tctx, b,
8826 : server_name_slash,
8827 : t->driver.info8.driver_name,
8828 : t->driver.info8.architecture,
8829 : DPD_DELETE_ALL_FILES,
8830 0 : t->driver.info8.version,
8831 0 : WERR_OK);
8832 0 : if (!ok) {
8833 0 : torture_warning(tctx,
8834 : "failed to delete printer driver via "
8835 : "spoolss\n");
8836 : }
8837 : }
8838 :
8839 8 : return ok;
8840 : }
8841 :
8842 16 : static bool torture_rpc_spoolss_printer_teardown(struct torture_context *tctx, void *data)
8843 : {
8844 16 : struct torture_printer_context *t = talloc_get_type(data, struct torture_printer_context);
8845 0 : bool ret;
8846 :
8847 16 : ret = torture_rpc_spoolss_printer_teardown_common(tctx, t);
8848 16 : talloc_free(t);
8849 :
8850 16 : return ret;
8851 : }
8852 :
8853 8 : static bool test_print_test(struct torture_context *tctx,
8854 : void *private_data)
8855 : {
8856 0 : struct torture_printer_context *t =
8857 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8858 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
8859 8 : struct dcerpc_binding_handle *b = p->binding_handle;
8860 :
8861 8 : torture_assert(tctx,
8862 : test_PausePrinter(tctx, b, &t->handle),
8863 : "failed to pause printer");
8864 :
8865 8 : torture_assert(tctx,
8866 : test_DoPrintTest(tctx, b, &t->handle),
8867 : "failed to do print test");
8868 :
8869 4 : torture_assert(tctx,
8870 : test_ResumePrinter(tctx, b, &t->handle),
8871 : "failed to resume printer");
8872 :
8873 4 : return true;
8874 : }
8875 :
8876 8 : static bool test_print_test_extended(struct torture_context *tctx,
8877 : void *private_data)
8878 : {
8879 0 : struct torture_printer_context *t =
8880 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8881 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
8882 8 : struct dcerpc_binding_handle *b = p->binding_handle;
8883 8 : bool ret = true;
8884 :
8885 8 : torture_assert(tctx,
8886 : test_PausePrinter(tctx, b, &t->handle),
8887 : "failed to pause printer");
8888 :
8889 8 : ret = test_DoPrintTest_extended(tctx, b, &t->handle);
8890 8 : if (ret == false) {
8891 4 : torture_comment(tctx, "WARNING! failed to do extended print test\n");
8892 4 : if (torture_setting_bool(tctx, "samba3", false)) {
8893 4 : torture_comment(tctx, "non-critical for samba3\n");
8894 4 : ret = true;
8895 4 : tctx->last_result = TORTURE_SKIP;
8896 : }
8897 : }
8898 :
8899 8 : torture_assert(tctx,
8900 : test_ResumePrinter(tctx, b, &t->handle),
8901 : "failed to resume printer");
8902 :
8903 8 : return ret;
8904 : }
8905 :
8906 8 : static bool test_print_test_properties(struct torture_context *tctx,
8907 : void *private_data)
8908 : {
8909 0 : struct torture_printer_context *t =
8910 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8911 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
8912 8 : struct dcerpc_binding_handle *b = p->binding_handle;
8913 :
8914 8 : if (torture_setting_bool(tctx, "samba3", false)) {
8915 8 : torture_skip(tctx, "skip printer job property tests against samba");
8916 : }
8917 :
8918 0 : torture_assert(tctx,
8919 : test_PausePrinter(tctx, b, &t->handle),
8920 : "failed to pause printer");
8921 :
8922 0 : torture_assert(tctx,
8923 : test_DoPrintTest_properties(tctx, b, &t->handle),
8924 : "failed to test print job properties");
8925 :
8926 0 : torture_assert(tctx,
8927 : test_ResumePrinter(tctx, b, &t->handle),
8928 : "failed to resume printer");
8929 :
8930 0 : return true;
8931 : }
8932 :
8933 : /* use smbd file IO to spool a print job */
8934 8 : static bool test_print_test_smbd(struct torture_context *tctx,
8935 : void *private_data)
8936 : {
8937 0 : struct torture_printer_context *t =
8938 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8939 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
8940 8 : struct dcerpc_binding_handle *b = p->binding_handle;
8941 0 : NTSTATUS status;
8942 0 : uint32_t count;
8943 8 : union spoolss_JobInfo *info = NULL;
8944 0 : int i;
8945 :
8946 0 : struct smb2_tree *tree;
8947 0 : struct smb2_handle job_h;
8948 0 : struct smbcli_options options;
8949 8 : TALLOC_CTX *mem_ctx = talloc_new(tctx);
8950 : /*
8951 : * Do not test against the dynamically added printers, printing via
8952 : * smbd means that a different spoolss process may handle the
8953 : * OpenPrinter request to the one that handled the AddPrinter request.
8954 : * This currently leads to an ugly race condition where one process
8955 : * sees the new printer and one doesn't.
8956 : */
8957 8 : const char *share = TORTURE_PRINTER_STATIC1;
8958 :
8959 8 : torture_comment(tctx, "Testing smbd job spooling\n");
8960 8 : lpcfg_smbcli_options(tctx->lp_ctx, &options);
8961 :
8962 8 : status = smb2_connect(mem_ctx,
8963 : torture_setting_string(tctx, "host", NULL),
8964 : lpcfg_smb_ports(tctx->lp_ctx),
8965 : share,
8966 : lpcfg_resolve_context(tctx->lp_ctx),
8967 : samba_cmdline_get_creds(),
8968 : &tree,
8969 : tctx->ev,
8970 : &options,
8971 : lpcfg_socket_options(tctx->lp_ctx),
8972 : lpcfg_gensec_settings(tctx, tctx->lp_ctx));
8973 8 : if (!NT_STATUS_IS_OK(status)) {
8974 0 : printf("Failed to connect to SMB2 printer %s - %s\n",
8975 : share, nt_errstr(status));
8976 0 : return false;
8977 : }
8978 :
8979 8 : status = torture_smb2_testfile(tree, "smbd_spooler_job", &job_h);
8980 8 : torture_assert_ntstatus_ok(tctx, status, "smbd spool job create");
8981 :
8982 8 : status = smb2_util_write(tree, job_h, "exciting print job data", 0,
8983 : sizeof("exciting print job data"));
8984 8 : torture_assert_ntstatus_ok(tctx, status, "smbd spool job write");
8985 :
8986 : /* check back end spoolss job was created */
8987 8 : torture_assert(tctx,
8988 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
8989 : &count, &info),
8990 : "EnumJobs level 1 failed");
8991 :
8992 8 : for (i = 0; i < count; i++) {
8993 0 : if (!strcmp(info[i].info1.document_name, "smbd_spooler_job")) {
8994 0 : break;
8995 : }
8996 : }
8997 8 : torture_assert(tctx, (i != count), "smbd_spooler_job not found");
8998 :
8999 0 : status = smb2_util_close(tree, job_h);
9000 0 : torture_assert_ntstatus_ok(tctx, status, "smbd spool job close");
9001 :
9002 : /* disconnect from printer share */
9003 0 : talloc_free(mem_ctx);
9004 :
9005 0 : return true;
9006 : }
9007 :
9008 8 : static bool test_print_test_purge(struct torture_context *tctx,
9009 : void *private_data)
9010 : {
9011 0 : struct torture_printer_context *t =
9012 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data,
9013 : struct torture_printer_context);
9014 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9015 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9016 8 : uint32_t num_jobs = 8;
9017 0 : uint32_t *job_ids;
9018 0 : int i;
9019 8 : bool ret = true;
9020 0 : uint32_t count;
9021 0 : union spoolss_JobInfo *info;
9022 :
9023 8 : torture_assert(tctx,
9024 : test_PausePrinter(tctx, b, &t->handle),
9025 : "failed to pause printer");
9026 :
9027 8 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
9028 72 : for (i=0; i < num_jobs; i++) {
9029 64 : ret = test_DoPrintTest_add_one_job(tctx, b, &t->handle,
9030 : "TorturePrintJob",
9031 64 : &job_ids[i]);
9032 64 : torture_assert(tctx, ret, "failed to add print job");
9033 : }
9034 :
9035 8 : torture_assert(tctx,
9036 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9037 : &count, &info),
9038 : "EnumJobs level 1 failed");
9039 :
9040 8 : torture_assert_int_equal(tctx, count, num_jobs,
9041 : "unexpected number of jobs in queue");
9042 :
9043 4 : torture_assert(tctx,
9044 : test_printer_purge(tctx, b, &t->handle),
9045 : "failed to purge printer");
9046 :
9047 4 : torture_assert(tctx,
9048 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9049 : &count, &info),
9050 : "EnumJobs level 1 failed");
9051 :
9052 4 : torture_assert_int_equal(tctx, count, 0,
9053 : "unexpected number of jobs in queue");
9054 :
9055 4 : torture_assert(tctx,
9056 : test_ResumePrinter(tctx, b, &t->handle),
9057 : "failed to resume printer");
9058 :
9059 4 : return true;
9060 : }
9061 :
9062 8 : static bool test_printer_sd(struct torture_context *tctx,
9063 : void *private_data)
9064 : {
9065 0 : struct torture_printer_context *t =
9066 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9067 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9068 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9069 :
9070 8 : torture_assert(tctx,
9071 : test_PrinterInfo_SD(tctx, b, &t->handle),
9072 : "failed to test security descriptors");
9073 :
9074 8 : return true;
9075 : }
9076 :
9077 8 : static bool test_printer_dm(struct torture_context *tctx,
9078 : void *private_data)
9079 : {
9080 0 : struct torture_printer_context *t =
9081 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9082 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9083 :
9084 8 : torture_assert(tctx,
9085 : test_PrinterInfo_DevMode(tctx, p, &t->handle, t->info2.printername, t->devmode),
9086 : "failed to test devicemodes");
9087 :
9088 8 : return true;
9089 : }
9090 :
9091 8 : static bool test_printer_info_winreg(struct torture_context *tctx,
9092 : void *private_data)
9093 : {
9094 0 : struct torture_printer_context *t =
9095 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9096 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9097 :
9098 8 : torture_assert(tctx,
9099 : test_PrinterInfo_winreg(tctx, p, &t->handle, t->info2.printername),
9100 : "failed to test printer info winreg");
9101 :
9102 8 : return true;
9103 : }
9104 :
9105 4 : static bool test_printserver_info_winreg(struct torture_context *tctx,
9106 : void *private_data)
9107 : {
9108 0 : struct test_spoolss_context *t =
9109 4 : (struct test_spoolss_context *)talloc_get_type_abort(private_data, struct test_spoolss_context);
9110 4 : struct dcerpc_pipe *p = t->spoolss_pipe;
9111 :
9112 4 : torture_assert(tctx,
9113 : test_PrintserverInfo_winreg(tctx, p, &t->server_handle),
9114 : "failed to test printserver info winreg");
9115 :
9116 4 : return true;
9117 : }
9118 :
9119 :
9120 8 : static bool test_printer_change_id(struct torture_context *tctx,
9121 : void *private_data)
9122 : {
9123 0 : struct torture_printer_context *t =
9124 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9125 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9126 :
9127 8 : torture_assert(tctx,
9128 : test_ChangeID(tctx, p, &t->handle),
9129 : "failed to test change id");
9130 :
9131 8 : return true;
9132 : }
9133 :
9134 8 : static bool test_printer_keys(struct torture_context *tctx,
9135 : void *private_data)
9136 : {
9137 0 : struct torture_printer_context *t =
9138 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9139 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9140 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9141 :
9142 8 : torture_assert(tctx,
9143 : test_printer_all_keys(tctx, b, &t->handle),
9144 : "failed to test printer keys");
9145 :
9146 8 : return true;
9147 : }
9148 :
9149 8 : static bool test_printer_data_consistency(struct torture_context *tctx,
9150 : void *private_data)
9151 : {
9152 0 : struct torture_printer_context *t =
9153 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9154 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9155 :
9156 8 : torture_assert(tctx,
9157 : test_EnumPrinterData_consistency(tctx, p, &t->handle),
9158 : "failed to test printer data consistency");
9159 :
9160 8 : return true;
9161 : }
9162 :
9163 8 : static bool test_printer_data_keys(struct torture_context *tctx,
9164 : void *private_data)
9165 : {
9166 0 : struct torture_printer_context *t =
9167 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9168 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9169 :
9170 8 : torture_assert(tctx,
9171 : test_SetPrinterDataEx_keys(tctx, p, &t->handle),
9172 : "failed to test printer data keys");
9173 :
9174 8 : return true;
9175 : }
9176 :
9177 8 : static bool test_printer_data_values(struct torture_context *tctx,
9178 : void *private_data)
9179 : {
9180 0 : struct torture_printer_context *t =
9181 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9182 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9183 :
9184 8 : torture_assert(tctx,
9185 : test_SetPrinterDataEx_values(tctx, p, &t->handle),
9186 : "failed to test printer data values");
9187 :
9188 8 : return true;
9189 : }
9190 :
9191 8 : static bool test_printer_data_set(struct torture_context *tctx,
9192 : void *private_data)
9193 : {
9194 0 : struct torture_printer_context *t =
9195 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9196 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9197 :
9198 8 : torture_assert(tctx,
9199 : test_SetPrinterDataEx_matrix(tctx, p, &t->handle, t->info2.printername, NULL, NULL),
9200 : "failed to test printer data set");
9201 :
9202 8 : return true;
9203 : }
9204 :
9205 8 : static bool test_printer_data_winreg(struct torture_context *tctx,
9206 : void *private_data)
9207 : {
9208 0 : struct torture_printer_context *t =
9209 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9210 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9211 :
9212 8 : torture_assert(tctx,
9213 : test_PrinterData_winreg(tctx, p, &t->handle, t->info2.printername),
9214 : "failed to test printer data winreg");
9215 :
9216 8 : return true;
9217 : }
9218 :
9219 8 : static bool test_printer_data_dsspooler(struct torture_context *tctx,
9220 : void *private_data)
9221 : {
9222 0 : struct torture_printer_context *t =
9223 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9224 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9225 :
9226 8 : torture_assert(tctx,
9227 : test_PrinterData_DsSpooler(tctx, p, &t->handle, t->info2.printername),
9228 : "failed to test printer data winreg dsspooler");
9229 :
9230 8 : return true;
9231 : }
9232 :
9233 8 : static bool test_printer_ic(struct torture_context *tctx,
9234 : void *private_data)
9235 : {
9236 0 : struct torture_printer_context *t =
9237 8 : talloc_get_type_abort(private_data,
9238 : struct torture_printer_context);
9239 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9240 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9241 0 : struct policy_handle gdi_handle;
9242 :
9243 8 : if (torture_setting_bool(tctx, "samba3", false)) {
9244 8 : torture_skip(tctx, "skip printer information context tests against samba");
9245 : }
9246 :
9247 : {
9248 0 : struct spoolss_CreatePrinterIC r;
9249 0 : struct spoolss_DevmodeContainer devmode_ctr;
9250 :
9251 0 : ZERO_STRUCT(devmode_ctr);
9252 :
9253 0 : r.in.handle = &t->handle;
9254 0 : r.in.devmode_ctr = &devmode_ctr;
9255 0 : r.out.gdi_handle = &gdi_handle;
9256 :
9257 0 : torture_assert_ntstatus_ok(tctx,
9258 : dcerpc_spoolss_CreatePrinterIC_r(b, tctx, &r),
9259 : "CreatePrinterIC failed");
9260 0 : torture_assert_werr_ok(tctx, r.out.result,
9261 : "CreatePrinterIC failed");
9262 : }
9263 :
9264 : {
9265 0 : struct spoolss_PlayGDIScriptOnPrinterIC r;
9266 0 : DATA_BLOB in,out;
9267 0 : int i;
9268 0 : uint32_t num_fonts = 0;
9269 :
9270 0 : in = data_blob_string_const("");
9271 :
9272 0 : r.in.gdi_handle = &gdi_handle;
9273 0 : r.in.pIn = in.data;
9274 0 : r.in.cIn = in.length;
9275 0 : r.in.ul = 0;
9276 :
9277 0 : for (i = 0; i < 4; i++) {
9278 :
9279 0 : out = data_blob_talloc_zero(tctx, i);
9280 :
9281 0 : r.in.cOut = out.length;
9282 0 : r.out.pOut = out.data;
9283 :
9284 0 : torture_assert_ntstatus_ok(tctx,
9285 : dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r(b, tctx, &r),
9286 : "PlayGDIScriptOnPrinterIC failed");
9287 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_ENOUGH_MEMORY,
9288 : "PlayGDIScriptOnPrinterIC failed");
9289 : }
9290 :
9291 0 : out = data_blob_talloc_zero(tctx, 4);
9292 :
9293 0 : r.in.cOut = out.length;
9294 0 : r.out.pOut = out.data;
9295 :
9296 0 : torture_assert_ntstatus_ok(tctx,
9297 : dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r(b, tctx, &r),
9298 : "PlayGDIScriptOnPrinterIC failed");
9299 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9300 : "PlayGDIScriptOnPrinterIC failed");
9301 :
9302 : /* now we should have the required length, so retry with a
9303 : * buffer which is large enough to carry all font ids */
9304 :
9305 0 : num_fonts = IVAL(r.out.pOut, 0);
9306 :
9307 0 : torture_comment(tctx, "PlayGDIScriptOnPrinterIC gave font count of %d\n", num_fonts);
9308 :
9309 0 : out = data_blob_talloc_zero(tctx,
9310 0 : num_fonts * sizeof(struct UNIVERSAL_FONT_ID) + 4);
9311 :
9312 0 : r.in.cOut = out.length;
9313 0 : r.out.pOut = out.data;
9314 :
9315 0 : torture_assert_ntstatus_ok(tctx,
9316 : dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r(b, tctx, &r),
9317 : "PlayGDIScriptOnPrinterIC failed");
9318 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9319 : "PlayGDIScriptOnPrinterIC failed");
9320 :
9321 : }
9322 :
9323 : {
9324 0 : struct spoolss_DeletePrinterIC r;
9325 :
9326 0 : r.in.gdi_handle = &gdi_handle;
9327 0 : r.out.gdi_handle = &gdi_handle;
9328 :
9329 0 : torture_assert_ntstatus_ok(tctx,
9330 : dcerpc_spoolss_DeletePrinterIC_r(b, tctx, &r),
9331 : "DeletePrinterIC failed");
9332 0 : torture_assert_werr_ok(tctx, r.out.result,
9333 : "DeletePrinterIC failed");
9334 :
9335 : }
9336 :
9337 0 : return true;
9338 : }
9339 :
9340 8 : static bool test_printer_bidi(struct torture_context *tctx,
9341 : void *private_data)
9342 : {
9343 0 : struct torture_printer_context *t =
9344 8 : talloc_get_type_abort(private_data,
9345 : struct torture_printer_context);
9346 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9347 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9348 0 : struct spoolss_SendRecvBidiData r;
9349 0 : struct RPC_BIDI_REQUEST_CONTAINER bidi_req;
9350 8 : struct RPC_BIDI_RESPONSE_CONTAINER *bidi_rep = NULL;
9351 :
9352 8 : if (torture_setting_bool(tctx, "samba3", false)) {
9353 8 : torture_skip(tctx, "skip printer bidirectional tests against samba");
9354 : }
9355 :
9356 0 : ZERO_STRUCT(bidi_req);
9357 :
9358 0 : r.in.hPrinter = t->handle;
9359 0 : r.in.pAction = "foobar";
9360 0 : r.in.pReqData = &bidi_req;
9361 0 : r.out.ppRespData = &bidi_rep;
9362 :
9363 0 : torture_assert_ntstatus_ok(tctx,
9364 : dcerpc_spoolss_SendRecvBidiData_r(b, tctx, &r),
9365 : "SendRecvBidiData failed");
9366 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
9367 : "SendRecvBidiData failed");
9368 :
9369 0 : if (!(t->info2.attributes & PRINTER_ATTRIBUTE_ENABLE_BIDI)) {
9370 0 : torture_skip(tctx, "skipping further tests as printer is not BIDI enabled");
9371 : }
9372 :
9373 0 : r.in.pAction = BIDI_ACTION_ENUM_SCHEMA;
9374 :
9375 0 : torture_assert_ntstatus_ok(tctx,
9376 : dcerpc_spoolss_SendRecvBidiData_r(b, tctx, &r),
9377 : "SendRecvBidiData failed");
9378 0 : torture_assert_werr_ok(tctx, r.out.result,
9379 : "SendRecvBidiData failed");
9380 :
9381 0 : return true;
9382 : }
9383 :
9384 8 : static bool test_printer_set_publish(struct torture_context *tctx,
9385 : struct dcerpc_binding_handle *b,
9386 : struct policy_handle *handle)
9387 : {
9388 0 : union spoolss_PrinterInfo info;
9389 0 : struct spoolss_SetPrinterInfo7 info7;
9390 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
9391 0 : struct spoolss_DevmodeContainer devmode_ctr;
9392 0 : struct sec_desc_buf secdesc_ctr;
9393 :
9394 8 : info7.guid = "";
9395 8 : info7.action = DSPRINT_PUBLISH;
9396 :
9397 8 : ZERO_STRUCT(info_ctr);
9398 8 : ZERO_STRUCT(devmode_ctr);
9399 8 : ZERO_STRUCT(secdesc_ctr);
9400 8 : info_ctr.level = 7;
9401 8 : info_ctr.info.info7 = &info7;
9402 :
9403 8 : torture_assert(tctx,
9404 : test_SetPrinter(tctx, b, handle, &info_ctr,
9405 : &devmode_ctr, &secdesc_ctr, 0), "");
9406 :
9407 0 : torture_assert(tctx,
9408 : test_GetPrinter_level(tctx, b, handle, 2, &info),
9409 : "");
9410 0 : torture_assert(tctx,
9411 : (info.info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED),
9412 : "info2 publish flag not set");
9413 0 : torture_assert(tctx,
9414 : test_GetPrinter_level(tctx, b, handle, 7, &info),
9415 : "");
9416 0 : if (info.info7.action & DSPRINT_PENDING) {
9417 0 : torture_comment(tctx, "publish is pending\n");
9418 0 : torture_assert_int_equal(tctx,
9419 : info.info7.action,
9420 : (DSPRINT_PENDING | DSPRINT_PUBLISH),
9421 : "info7 publish flag not set");
9422 : } else {
9423 0 : struct GUID guid;
9424 0 : char *ref_guid;
9425 0 : torture_assert_int_equal(tctx,
9426 : info.info7.action,
9427 : DSPRINT_PUBLISH,
9428 : "info7 publish flag not set");
9429 :
9430 : /* GUID_from_string is able to parse both plain and
9431 : * curly-braced guids */
9432 0 : torture_assert_ntstatus_ok(tctx,
9433 : GUID_from_string(info.info7.guid,
9434 : &guid),
9435 : "invalid published printer GUID");
9436 :
9437 : /* Build reference GUID string */
9438 0 : ref_guid = GUID_string2(tctx, &guid);
9439 0 : torture_assert_not_null(tctx, ref_guid, "ENOMEM");
9440 0 : ref_guid = talloc_strdup_upper(tctx, ref_guid);
9441 0 : torture_assert_not_null(tctx, ref_guid, "ENOMEM");
9442 0 : torture_assert_str_equal(tctx, info.info7.guid, ref_guid,
9443 : "invalid GUID format");
9444 : }
9445 :
9446 0 : return true;
9447 : }
9448 :
9449 0 : static bool test_printer_set_unpublish(struct torture_context *tctx,
9450 : struct dcerpc_binding_handle *b,
9451 : struct policy_handle *handle)
9452 : {
9453 0 : union spoolss_PrinterInfo info;
9454 0 : struct spoolss_SetPrinterInfo7 info7;
9455 0 : struct spoolss_SetPrinterInfoCtr info_ctr;
9456 0 : struct spoolss_DevmodeContainer devmode_ctr;
9457 0 : struct sec_desc_buf secdesc_ctr;
9458 :
9459 0 : info7.action = DSPRINT_UNPUBLISH;
9460 0 : info7.guid = "";
9461 :
9462 0 : ZERO_STRUCT(info_ctr);
9463 0 : ZERO_STRUCT(devmode_ctr);
9464 0 : ZERO_STRUCT(secdesc_ctr);
9465 0 : info_ctr.level = 7;
9466 0 : info_ctr.info.info7 = &info7;
9467 :
9468 0 : torture_assert(tctx,
9469 : test_SetPrinter(tctx, b, handle, &info_ctr,
9470 : &devmode_ctr, &secdesc_ctr, 0), "");
9471 :
9472 0 : torture_assert(tctx,
9473 : test_GetPrinter_level(tctx, b, handle, 2, &info),
9474 : "");
9475 0 : torture_assert(tctx,
9476 : !(info.info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED),
9477 : "info2 publish flag still set");
9478 0 : torture_assert(tctx,
9479 : test_GetPrinter_level(tctx, b, handle, 7, &info),
9480 : "");
9481 :
9482 0 : if (info.info7.action & DSPRINT_PENDING) {
9483 0 : struct GUID guid;
9484 0 : torture_comment(tctx, "unpublish is pending\n");
9485 0 : torture_assert_int_equal(tctx,
9486 : info.info7.action,
9487 : (DSPRINT_PENDING | DSPRINT_UNPUBLISH),
9488 : "info7 unpublish flag not set");
9489 0 : torture_assert_ntstatus_ok(tctx,
9490 : GUID_from_string(info.info7.guid,
9491 : &guid),
9492 : "invalid printer GUID");
9493 : } else {
9494 0 : torture_assert_int_equal(tctx,
9495 : info.info7.action, DSPRINT_UNPUBLISH,
9496 : "info7 unpublish flag not set");
9497 : }
9498 :
9499 0 : return true;
9500 : }
9501 :
9502 8 : static bool test_printer_publish_toggle(struct torture_context *tctx,
9503 : void *private_data)
9504 : {
9505 0 : struct torture_printer_context *t =
9506 8 : talloc_get_type_abort(private_data,
9507 : struct torture_printer_context);
9508 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9509 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9510 8 : struct policy_handle *handle = &t->handle;
9511 0 : union spoolss_PrinterInfo info7;
9512 0 : union spoolss_PrinterInfo info2;
9513 :
9514 : /* check publish status via level 7 and level 2 */
9515 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 7, &info7),
9516 : "");
9517 8 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info2),
9518 : "");
9519 :
9520 8 : if (info2.info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
9521 0 : torture_assert_int_equal(tctx,
9522 : info7.info7.action, DSPRINT_PUBLISH,
9523 : "info7 publish flag not set");
9524 0 : torture_assert(tctx, test_printer_set_unpublish(tctx, b, handle), "");
9525 0 : torture_assert(tctx, test_printer_set_publish(tctx, b, handle), "");
9526 : } else {
9527 8 : torture_assert_int_equal(tctx,
9528 : info7.info7.action, DSPRINT_UNPUBLISH,
9529 : "info7 unpublish flag not set");
9530 8 : torture_assert(tctx, test_printer_set_publish(tctx, b, handle), "");
9531 0 : torture_assert(tctx, test_printer_set_unpublish(tctx, b, handle), "");
9532 : }
9533 :
9534 0 : return true;
9535 : }
9536 :
9537 8 : static bool test_driver_info_winreg(struct torture_context *tctx,
9538 : void *private_data)
9539 : {
9540 0 : struct torture_printer_context *t =
9541 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9542 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9543 8 : const char *driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
9544 :
9545 8 : if (!t->have_driver) {
9546 8 : torture_skip(tctx, "skipping driver info winreg test as we don't have a driver");
9547 : }
9548 :
9549 0 : torture_assert(tctx,
9550 : test_DriverInfo_winreg(tctx, p, &t->handle, t->info2.printername, driver_name, t->driver.remote.environment, 3),
9551 : "failed to test driver info winreg");
9552 :
9553 0 : return true;
9554 : }
9555 :
9556 8 : static bool test_print_job_enum(struct torture_context *tctx,
9557 : void *private_data)
9558 : {
9559 0 : struct torture_printer_context *t =
9560 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9561 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9562 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9563 8 : bool ret = true;
9564 8 : uint32_t num_jobs = 8;
9565 0 : uint32_t *job_ids;
9566 0 : int i;
9567 8 : union spoolss_JobInfo *info = NULL;
9568 0 : uint32_t count;
9569 :
9570 8 : torture_assert(tctx,
9571 : test_PausePrinter(tctx, b, &t->handle),
9572 : "failed to pause printer");
9573 :
9574 : /* purge in case of any jobs from previous tests */
9575 8 : torture_assert(tctx,
9576 : test_printer_purge(tctx, b, &t->handle),
9577 : "failed to purge printer");
9578 :
9579 : /* enum before jobs, valid level */
9580 8 : torture_assert(tctx,
9581 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9582 : &count, &info),
9583 : "EnumJobs with valid level");
9584 8 : torture_assert_int_equal(tctx, count, 0, "EnumJobs count");
9585 8 : torture_assert(tctx,
9586 : test_EnumJobs_args(tctx, b, &t->handle, 2, WERR_OK,
9587 : &count, &info),
9588 : "EnumJobs with valid level");
9589 8 : torture_assert_int_equal(tctx, count, 0, "EnumJobs count");
9590 : /* enum before jobs, invalid level - expect failure */
9591 8 : torture_assert(tctx,
9592 : test_EnumJobs_args(tctx, b, &t->handle, 100,
9593 : WERR_INVALID_LEVEL,
9594 : &count, &info),
9595 : "EnumJobs with invalid level");
9596 :
9597 8 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
9598 :
9599 72 : for (i = 0; i < num_jobs; i++) {
9600 64 : ret = test_DoPrintTest_add_one_job(tctx, b, &t->handle,
9601 : "TorturePrintJob",
9602 64 : &job_ids[i]);
9603 64 : torture_assert(tctx, ret, "failed to add print job");
9604 : }
9605 :
9606 : /* enum after jobs, valid level */
9607 8 : torture_assert(tctx,
9608 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9609 : &count, &info),
9610 : "EnumJobs with valid level");
9611 8 : torture_assert_int_equal(tctx, count, num_jobs, "EnumJobs count");
9612 4 : torture_assert(tctx,
9613 : test_EnumJobs_args(tctx, b, &t->handle, 2, WERR_OK,
9614 : &count, &info),
9615 : "EnumJobs with valid level");
9616 4 : torture_assert_int_equal(tctx, count, num_jobs, "EnumJobs count");
9617 : /* enum after jobs, invalid level - expect failure */
9618 4 : torture_assert(tctx,
9619 : test_EnumJobs_args(tctx, b, &t->handle, 100,
9620 : WERR_INVALID_LEVEL,
9621 : &count, &info),
9622 : "EnumJobs with invalid level");
9623 :
9624 36 : for (i = 0; i < num_jobs; i++) {
9625 32 : test_SetJob(tctx, b, &t->handle, job_ids[i], NULL,
9626 : SPOOLSS_JOB_CONTROL_DELETE);
9627 : }
9628 :
9629 4 : torture_assert(tctx,
9630 : test_ResumePrinter(tctx, b, &t->handle),
9631 : "failed to resume printer");
9632 :
9633 4 : return true;
9634 : }
9635 :
9636 8 : static bool test_printer_log_jobinfo(struct torture_context *tctx,
9637 : void *private_data)
9638 : {
9639 0 : struct torture_printer_context *t =
9640 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9641 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9642 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9643 0 : struct spoolss_BranchOfficeJobDataContainer info;
9644 0 : int i;
9645 :
9646 0 : struct spoolss_LogJobInfoForBranchOffice r;
9647 :
9648 8 : torture_comment(tctx, "Testing LogJobInfoForBranchOffice\n");
9649 :
9650 8 : info.cJobDataEntries = 0;
9651 8 : info.JobData = NULL;
9652 :
9653 8 : r.in.hPrinter = &t->handle;
9654 8 : r.in.pBranchOfficeJobDataContainer = &info;
9655 :
9656 8 : torture_assert_ntstatus_ok(tctx,
9657 : dcerpc_spoolss_LogJobInfoForBranchOffice_r(b, tctx, &r),
9658 : "LogJobInfoForBranchOffice failed");
9659 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
9660 : "LogJobInfoForBranchOffice failed");
9661 :
9662 0 : info.cJobDataEntries = 1;
9663 0 : info.JobData = talloc_zero_array(tctx, struct spoolss_BranchOfficeJobData, info.cJobDataEntries);
9664 :
9665 0 : info.JobData[0].eEventType = kLogOfflineFileFull;
9666 0 : info.JobData[0].JobId = 42;
9667 0 : info.JobData[0].JobInfo.LogOfflineFileFull.pMachineName = talloc_strdup(tctx, "mthelena");
9668 :
9669 0 : torture_assert_ntstatus_ok(tctx,
9670 : dcerpc_spoolss_LogJobInfoForBranchOffice_r(b, tctx, &r),
9671 : "LogJobInfoForBranchOffice failed");
9672 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9673 : "LogJobInfoForBranchOffice failed");
9674 :
9675 0 : info.cJobDataEntries = 42;
9676 0 : info.JobData = talloc_zero_array(tctx, struct spoolss_BranchOfficeJobData, info.cJobDataEntries);
9677 :
9678 0 : for (i=0; i < info.cJobDataEntries; i++) {
9679 0 : info.JobData[i].eEventType = kLogOfflineFileFull;
9680 0 : info.JobData[i].JobId = i;
9681 0 : info.JobData[i].JobInfo.LogOfflineFileFull.pMachineName = talloc_asprintf(tctx, "torture_%d", i);
9682 : }
9683 :
9684 0 : torture_assert_ntstatus_ok(tctx,
9685 : dcerpc_spoolss_LogJobInfoForBranchOffice_r(b, tctx, &r),
9686 : "LogJobInfoForBranchOffice failed");
9687 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9688 : "LogJobInfoForBranchOffice failed");
9689 :
9690 0 : return true;
9691 : }
9692 :
9693 8 : static bool test_printer_os_versions(struct torture_context *tctx,
9694 : void *private_data)
9695 : {
9696 0 : struct torture_printer_context *t =
9697 8 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9698 8 : struct dcerpc_pipe *p = t->spoolss_pipe;
9699 8 : struct dcerpc_binding_handle *b = p->binding_handle;
9700 0 : union spoolss_PrinterInfo info;
9701 0 : DATA_BLOB blob;
9702 0 : uint8_t *data;
9703 0 : uint32_t length;
9704 0 : struct spoolss_OSVersion osversion;
9705 0 : uint8_t os_major, os_minor;
9706 0 : uint16_t os_build;
9707 0 : struct policy_handle server_handle;
9708 :
9709 8 : torture_comment(tctx, "Testing OSVersion vs. PRINTER_INFO_STRESS\n");
9710 :
9711 8 : torture_assert(tctx,
9712 : test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
9713 : "failed to get level 0 printer info");
9714 :
9715 8 : torture_assert(tctx,
9716 : test_OpenPrinter_server(tctx, p, &server_handle),
9717 : "failed to open printserver");
9718 :
9719 8 : torture_assert(tctx,
9720 : test_GetPrinterData_checktype(tctx, b, &server_handle, "OSVersion",
9721 : NULL, NULL, &data, &length),
9722 : "failed to fetch OSVersion printer data");
9723 :
9724 8 : test_ClosePrinter(tctx, b, &server_handle);
9725 :
9726 8 : blob = data_blob_const(data, length);
9727 :
9728 8 : torture_assert_ndr_success(tctx,
9729 : ndr_pull_struct_blob(&blob, tctx, &osversion,
9730 : (ndr_pull_flags_fn_t)ndr_pull_spoolss_OSVersion),
9731 : "failed to pull OSVersion");
9732 :
9733 8 : os_major = CVAL(&info.info0.version, 0);
9734 8 : os_minor = CVAL(&info.info0.version, 1);
9735 8 : os_build = SVAL(&info.info0.version, 2);
9736 :
9737 8 : torture_assert_int_equal(tctx, os_major, osversion.major, "major");
9738 8 : torture_assert_int_equal(tctx, os_minor, osversion.minor, "minor");
9739 8 : torture_assert_int_equal(tctx, os_build, osversion.build, "build");
9740 :
9741 8 : return true;
9742 : }
9743 :
9744 :
9745 4708 : void torture_tcase_printer(struct torture_tcase *tcase)
9746 : {
9747 4708 : torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter_wrap);
9748 4708 : torture_tcase_add_simple_test(tcase, "csetprinter", test_csetprinter);
9749 4708 : torture_tcase_add_simple_test(tcase, "print_test", test_print_test);
9750 4708 : torture_tcase_add_simple_test(tcase, "print_test_extended", test_print_test_extended);
9751 4708 : torture_tcase_add_simple_test(tcase, "print_test_smbd", test_print_test_smbd);
9752 4708 : torture_tcase_add_simple_test(tcase, "print_test_properties", test_print_test_properties);
9753 4708 : torture_tcase_add_simple_test(tcase, "print_test_purge", test_print_test_purge);
9754 4708 : torture_tcase_add_simple_test(tcase, "printer_info", test_printer_info);
9755 4708 : torture_tcase_add_simple_test(tcase, "sd", test_printer_sd);
9756 4708 : torture_tcase_add_simple_test(tcase, "dm", test_printer_dm);
9757 4708 : torture_tcase_add_simple_test(tcase, "printer_info_winreg", test_printer_info_winreg);
9758 4708 : torture_tcase_add_simple_test(tcase, "change_id", test_printer_change_id);
9759 4708 : torture_tcase_add_simple_test(tcase, "keys", test_printer_keys);
9760 4708 : torture_tcase_add_simple_test(tcase, "printerdata_consistency", test_printer_data_consistency);
9761 4708 : torture_tcase_add_simple_test(tcase, "printerdata_keys", test_printer_data_keys);
9762 4708 : torture_tcase_add_simple_test(tcase, "printerdata_values", test_printer_data_values);
9763 4708 : torture_tcase_add_simple_test(tcase, "printerdata_set", test_printer_data_set);
9764 4708 : torture_tcase_add_simple_test(tcase, "printerdata_winreg", test_printer_data_winreg);
9765 4708 : torture_tcase_add_simple_test(tcase, "printerdata_dsspooler", test_printer_data_dsspooler);
9766 4708 : torture_tcase_add_simple_test(tcase, "driver_info_winreg", test_driver_info_winreg);
9767 4708 : torture_tcase_add_simple_test(tcase, "printer_rename", test_printer_rename);
9768 4708 : torture_tcase_add_simple_test(tcase, "printer_ic", test_printer_ic);
9769 4708 : torture_tcase_add_simple_test(tcase, "bidi", test_printer_bidi);
9770 4708 : torture_tcase_add_simple_test(tcase, "publish_toggle",
9771 : test_printer_publish_toggle);
9772 4708 : torture_tcase_add_simple_test(tcase, "print_job_enum", test_print_job_enum);
9773 4708 : torture_tcase_add_simple_test(tcase, "log_jobinfo", test_printer_log_jobinfo);
9774 4708 : torture_tcase_add_simple_test(tcase, "os_versions", test_printer_os_versions);
9775 4708 : }
9776 :
9777 2354 : struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
9778 : {
9779 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "printer");
9780 125 : struct torture_tcase *tcase;
9781 :
9782 2354 : tcase = torture_suite_add_tcase(suite, "addprinter");
9783 :
9784 2354 : torture_tcase_set_fixture(tcase,
9785 : torture_rpc_spoolss_printer_setup,
9786 : torture_rpc_spoolss_printer_teardown);
9787 :
9788 2354 : torture_tcase_printer(tcase);
9789 :
9790 2354 : tcase = torture_suite_add_tcase(suite, "addprinterex");
9791 :
9792 2354 : torture_tcase_set_fixture(tcase,
9793 : torture_rpc_spoolss_printerex_setup,
9794 : torture_rpc_spoolss_printer_teardown);
9795 :
9796 2354 : torture_tcase_printer(tcase);
9797 :
9798 2354 : tcase = torture_suite_add_tcase(suite, "addprinterwkn");
9799 :
9800 2354 : torture_tcase_set_fixture(tcase,
9801 : torture_rpc_spoolss_printerwkn_setup,
9802 : torture_rpc_spoolss_printer_teardown);
9803 :
9804 2354 : tcase = torture_suite_add_tcase(suite, "addprinterexwkn");
9805 :
9806 2354 : torture_tcase_set_fixture(tcase,
9807 : torture_rpc_spoolss_printerexwkn_setup,
9808 : torture_rpc_spoolss_printer_teardown);
9809 :
9810 : #if 0
9811 : /* test is not correct */
9812 : tcase = torture_suite_add_tcase(suite, "addprinterdm");
9813 :
9814 : torture_tcase_set_fixture(tcase,
9815 : torture_rpc_spoolss_printerdm_setup,
9816 : torture_rpc_spoolss_printer_teardown);
9817 :
9818 : torture_tcase_printer(tcase);
9819 : #endif
9820 2354 : return suite;
9821 : }
9822 :
9823 2354 : struct torture_suite *torture_rpc_spoolss(TALLOC_CTX *mem_ctx)
9824 : {
9825 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss");
9826 2354 : struct torture_tcase *tcase = torture_suite_add_tcase(suite, "printserver");
9827 :
9828 2354 : torture_tcase_set_fixture(tcase,
9829 : torture_rpc_spoolss_setup,
9830 : torture_rpc_spoolss_teardown);
9831 :
9832 2354 : torture_tcase_add_simple_test(tcase, "openprinter_badnamelist", test_OpenPrinter_badname_list);
9833 2354 : torture_tcase_add_simple_test(tcase, "printer_data_list", test_GetPrinterData_list);
9834 2354 : torture_tcase_add_simple_test(tcase, "enum_forms", test_PrintServer_EnumForms);
9835 2354 : torture_tcase_add_simple_test(tcase, "forms", test_PrintServer_Forms);
9836 2354 : torture_tcase_add_simple_test(tcase, "forms_winreg", test_PrintServer_Forms_Winreg);
9837 2354 : torture_tcase_add_simple_test(tcase, "enum_ports", test_EnumPorts);
9838 2354 : torture_tcase_add_simple_test(tcase, "add_port", test_AddPort);
9839 2354 : torture_tcase_add_simple_test(tcase, "get_printer_driver_directory", test_GetPrinterDriverDirectory);
9840 2354 : torture_tcase_add_simple_test(tcase, "get_print_processor_directory", test_GetPrintProcessorDirectory);
9841 2354 : torture_tcase_add_simple_test(tcase, "enum_printer_drivers", test_EnumPrinterDrivers);
9842 2354 : torture_tcase_add_simple_test(tcase, "enum_monitors", test_EnumMonitors);
9843 2354 : torture_tcase_add_simple_test(tcase, "enum_print_processors", test_EnumPrintProcessors);
9844 2354 : torture_tcase_add_simple_test(tcase, "print_processors_winreg", test_print_processors_winreg);
9845 2354 : torture_tcase_add_simple_test(tcase, "add_processor", test_add_print_processor);
9846 2354 : torture_tcase_add_simple_test(tcase, "enum_printprocdata", test_EnumPrintProcessorDataTypes);
9847 2354 : torture_tcase_add_simple_test(tcase, "enum_printers", test_EnumPrinters);
9848 2354 : torture_tcase_add_simple_test(tcase, "enum_ports_old", test_EnumPorts_old);
9849 2354 : torture_tcase_add_simple_test(tcase, "enum_printers_old", test_EnumPrinters_old);
9850 2354 : torture_tcase_add_simple_test(tcase, "enum_printers_servername", test_EnumPrinters_servername);
9851 2354 : torture_tcase_add_simple_test(tcase, "enum_printer_drivers_old", test_EnumPrinterDrivers_old);
9852 2354 : torture_tcase_add_simple_test(tcase, "architecture_buffer", test_architecture_buffer);
9853 2354 : torture_tcase_add_simple_test(tcase, "get_core_printer_drivers", test_get_core_printer_drivers);
9854 2354 : torture_tcase_add_simple_test(tcase, "get_printer_driver_package_path", test_get_printer_driver_package_path);
9855 2354 : torture_tcase_add_simple_test(tcase, "get_printer", test_get_printer_printserverhandle);
9856 2354 : torture_tcase_add_simple_test(tcase, "set_printer", test_set_printer_printserverhandle);
9857 2354 : torture_tcase_add_simple_test(tcase, "printserver_info_winreg", test_printserver_info_winreg);
9858 2354 : torture_tcase_add_simple_test(tcase, "addpermachineconnection", test_addpermachineconnection);
9859 :
9860 2354 : torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
9861 :
9862 2354 : return suite;
9863 : }
9864 :
9865 64 : static bool test_GetPrinterDriverDirectory_getdir(struct torture_context *tctx,
9866 : struct dcerpc_binding_handle *b,
9867 : const char *server,
9868 : const char *environment,
9869 : const char **dir_p)
9870 : {
9871 0 : struct spoolss_GetPrinterDriverDirectory r;
9872 0 : uint32_t needed;
9873 :
9874 64 : r.in.server = server;
9875 64 : r.in.environment = environment;
9876 64 : r.in.level = 1;
9877 64 : r.in.buffer = NULL;
9878 64 : r.in.offered = 0;
9879 64 : r.out.needed = &needed;
9880 :
9881 64 : torture_assert_ntstatus_ok(tctx,
9882 : dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r),
9883 : "failed to query driver directory");
9884 :
9885 64 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
9886 64 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
9887 64 : r.in.buffer = &blob;
9888 64 : r.in.offered = needed;
9889 :
9890 64 : torture_assert_ntstatus_ok(tctx,
9891 : dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r),
9892 : "failed to query driver directory");
9893 : }
9894 :
9895 64 : torture_assert_werr_ok(tctx, r.out.result,
9896 : "failed to query driver directory");
9897 :
9898 64 : if (dir_p) {
9899 64 : *dir_p = r.out.info->info1.directory_name;
9900 : }
9901 :
9902 64 : return true;
9903 : }
9904 :
9905 0 : static const char *get_driver_from_info(struct spoolss_AddDriverInfoCtr *info_ctr)
9906 : {
9907 0 : if (info_ctr == NULL) {
9908 0 : return NULL;
9909 : }
9910 :
9911 0 : switch (info_ctr->level) {
9912 0 : case 1:
9913 0 : return info_ctr->info.info1->driver_name;
9914 0 : case 2:
9915 0 : return info_ctr->info.info2->driver_name;
9916 0 : case 3:
9917 0 : return info_ctr->info.info3->driver_name;
9918 0 : case 4:
9919 0 : return info_ctr->info.info4->driver_name;
9920 0 : case 6:
9921 0 : return info_ctr->info.info6->driver_name;
9922 0 : case 8:
9923 0 : return info_ctr->info.info8->driver_name;
9924 0 : default:
9925 0 : return NULL;
9926 : }
9927 : }
9928 :
9929 0 : static const char *get_environment_from_info(struct spoolss_AddDriverInfoCtr *info_ctr)
9930 : {
9931 0 : if (info_ctr == NULL) {
9932 0 : return NULL;
9933 : }
9934 :
9935 0 : switch (info_ctr->level) {
9936 0 : case 2:
9937 0 : return info_ctr->info.info2->architecture;
9938 0 : case 3:
9939 0 : return info_ctr->info.info3->architecture;
9940 0 : case 4:
9941 0 : return info_ctr->info.info4->architecture;
9942 0 : case 6:
9943 0 : return info_ctr->info.info6->architecture;
9944 0 : case 8:
9945 0 : return info_ctr->info.info8->architecture;
9946 0 : default:
9947 0 : return NULL;
9948 : }
9949 : }
9950 :
9951 :
9952 0 : static bool test_AddPrinterDriver_exp(struct torture_context *tctx,
9953 : struct dcerpc_binding_handle *b,
9954 : const char *servername,
9955 : struct spoolss_AddDriverInfoCtr *info_ctr,
9956 : WERROR expected_result)
9957 : {
9958 0 : struct spoolss_AddPrinterDriver r;
9959 0 : const char *drivername = get_driver_from_info(info_ctr);
9960 0 : const char *environment = get_environment_from_info(info_ctr);
9961 :
9962 0 : r.in.servername = servername;
9963 0 : r.in.info_ctr = info_ctr;
9964 :
9965 0 : torture_comment(tctx, "Testing AddPrinterDriver(%s) level: %d, environment: '%s'\n",
9966 : drivername, info_ctr->level, environment);
9967 :
9968 0 : torture_assert_ntstatus_ok(tctx,
9969 : dcerpc_spoolss_AddPrinterDriver_r(b, tctx, &r),
9970 : "spoolss_AddPrinterDriver failed");
9971 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
9972 : "spoolss_AddPrinterDriver failed with unexpected result");
9973 :
9974 0 : return true;
9975 :
9976 : }
9977 :
9978 0 : static bool test_AddPrinterDriverEx_exp(struct torture_context *tctx,
9979 : struct dcerpc_binding_handle *b,
9980 : const char *servername,
9981 : struct spoolss_AddDriverInfoCtr *info_ctr,
9982 : uint32_t flags,
9983 : WERROR expected_result)
9984 : {
9985 0 : struct spoolss_AddPrinterDriverEx r;
9986 0 : const char *drivername = get_driver_from_info(info_ctr);
9987 0 : const char *environment = get_environment_from_info(info_ctr);
9988 :
9989 0 : r.in.servername = servername;
9990 0 : r.in.info_ctr = info_ctr;
9991 0 : r.in.flags = flags;
9992 :
9993 0 : torture_comment(tctx, "Testing AddPrinterDriverEx(%s) level: %d, environment: '%s'\n",
9994 : drivername, info_ctr->level, environment);
9995 :
9996 0 : torture_assert_ntstatus_ok(tctx,
9997 : dcerpc_spoolss_AddPrinterDriverEx_r(b, tctx, &r),
9998 : "AddPrinterDriverEx failed");
9999 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
10000 : "AddPrinterDriverEx failed with unexpected result");
10001 :
10002 0 : return true;
10003 : }
10004 :
10005 : #define ASSERT_DRIVER_PATH(tctx, path, driver_dir, cmt) \
10006 : if (path && strlen(path)) {\
10007 : torture_assert_strn_equal(tctx, path, driver_dir, strlen(driver_dir), cmt); \
10008 : }
10009 :
10010 0 : static bool test_AddPrinterDriver_args_level_1(struct torture_context *tctx,
10011 : struct dcerpc_binding_handle *b,
10012 : const char *server_name,
10013 : struct spoolss_AddDriverInfo8 *r,
10014 : uint32_t flags,
10015 : bool ex,
10016 : const char *remote_driver_dir)
10017 : {
10018 0 : struct spoolss_AddDriverInfoCtr info_ctr;
10019 0 : struct spoolss_AddDriverInfo1 info1;
10020 :
10021 0 : ZERO_STRUCT(info1);
10022 :
10023 0 : info_ctr.level = 1;
10024 0 : info_ctr.info.info1 = &info1;
10025 :
10026 0 : if (ex) {
10027 0 : torture_assert(tctx,
10028 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_LEVEL),
10029 : "failed to test AddPrinterDriverEx level 1");
10030 : } else {
10031 0 : torture_assert(tctx,
10032 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10033 : "failed to test AddPrinterDriver level 1");
10034 : }
10035 :
10036 0 : info1.driver_name = r->driver_name;
10037 :
10038 0 : if (ex) {
10039 0 : torture_assert(tctx,
10040 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_LEVEL),
10041 : "failed to test AddPrinterDriverEx level 1");
10042 : } else {
10043 0 : torture_assert(tctx,
10044 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10045 : "failed to test AddPrinterDriver level 1");
10046 : }
10047 :
10048 0 : return true;
10049 : }
10050 :
10051 0 : static bool test_AddPrinterDriver_args_level_2(struct torture_context *tctx,
10052 : struct dcerpc_binding_handle *b,
10053 : const char *server_name,
10054 : struct spoolss_AddDriverInfo8 *r,
10055 : uint32_t flags,
10056 : bool ex,
10057 : const char *remote_driver_dir)
10058 : {
10059 0 : struct spoolss_AddDriverInfoCtr info_ctr;
10060 0 : struct spoolss_AddDriverInfo2 info2;
10061 0 : union spoolss_DriverInfo info;
10062 :
10063 0 : ZERO_STRUCT(info2);
10064 :
10065 0 : info_ctr.level = 2;
10066 0 : info_ctr.info.info2 = &info2;
10067 :
10068 0 : if (ex) {
10069 0 : torture_assert(tctx,
10070 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10071 : "failed to test AddPrinterDriverEx level 2");
10072 : } else {
10073 0 : torture_assert(tctx,
10074 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10075 : "failed to test AddPrinterDriver level 2");
10076 : }
10077 :
10078 0 : info2.driver_name = r->driver_name;
10079 :
10080 0 : if (ex) {
10081 0 : torture_assert(tctx,
10082 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10083 : "failed to test AddPrinterDriverEx level 2");
10084 : } else {
10085 0 : torture_assert(tctx,
10086 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10087 : "failed to test AddPrinterDriver level 2");
10088 : }
10089 :
10090 0 : info2.version = r->version;
10091 :
10092 0 : if (ex) {
10093 0 : torture_assert(tctx,
10094 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10095 : "failed to test AddPrinterDriverEx level 2");
10096 : } else {
10097 0 : torture_assert(tctx,
10098 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10099 : "failed to test AddPrinterDriver level 2");
10100 : }
10101 :
10102 0 : info2.architecture = r->architecture;
10103 :
10104 0 : if (ex) {
10105 0 : torture_assert(tctx,
10106 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10107 : "failed to test AddPrinterDriverEx level 2");
10108 : } else {
10109 0 : torture_assert(tctx,
10110 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10111 : "failed to test AddPrinterDriver level 2");
10112 : }
10113 :
10114 0 : info2.driver_path = r->driver_path;
10115 :
10116 0 : if (ex) {
10117 0 : torture_assert(tctx,
10118 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10119 : "failed to test AddPrinterDriverEx level 2");
10120 : } else {
10121 0 : torture_assert(tctx,
10122 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10123 : "failed to test AddPrinterDriver level 2");
10124 : }
10125 :
10126 0 : info2.data_file = r->data_file;
10127 :
10128 0 : if (ex) {
10129 0 : torture_assert(tctx,
10130 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10131 : "failed to test AddPrinterDriverEx level 2");
10132 : } else {
10133 0 : torture_assert(tctx,
10134 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10135 : "failed to test AddPrinterDriver level 2");
10136 : }
10137 :
10138 0 : info2.config_file = r->config_file;
10139 :
10140 0 : if (ex) {
10141 0 : torture_assert(tctx,
10142 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, 0, WERR_INVALID_PARAMETER),
10143 : "failed to test AddPrinterDriverEx");
10144 : }
10145 :
10146 0 : if (ex) {
10147 0 : torture_assert(tctx,
10148 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10149 : "failed to test AddPrinterDriverEx level 2");
10150 : } else {
10151 0 : torture_assert(tctx,
10152 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
10153 : "failed to test AddPrinterDriver level 2");
10154 : }
10155 :
10156 0 : torture_assert(tctx,
10157 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 2, r->driver_name, &info),
10158 : "failed to find added printer driver");
10159 :
10160 0 : if (remote_driver_dir) {
10161 0 : ASSERT_DRIVER_PATH(tctx, info.info2.driver_path, remote_driver_dir, "unexpected path");
10162 0 : ASSERT_DRIVER_PATH(tctx, info.info2.data_file, remote_driver_dir, "unexpected path");
10163 0 : ASSERT_DRIVER_PATH(tctx, info.info2.config_file, remote_driver_dir, "unexpected path");
10164 : }
10165 :
10166 0 : return true;
10167 : }
10168 :
10169 0 : static bool test_AddPrinterDriver_args_level_3(struct torture_context *tctx,
10170 : struct dcerpc_binding_handle *b,
10171 : const char *server_name,
10172 : struct spoolss_AddDriverInfo8 *r,
10173 : uint32_t flags,
10174 : bool ex,
10175 : const char *remote_driver_dir)
10176 : {
10177 0 : struct spoolss_AddDriverInfoCtr info_ctr;
10178 0 : struct spoolss_AddDriverInfo3 info3;
10179 0 : union spoolss_DriverInfo info;
10180 :
10181 0 : info3.driver_name = r->driver_name;
10182 0 : info3.version = r->version;
10183 0 : info3.architecture = r->architecture;
10184 0 : info3.driver_path = r->driver_path;
10185 0 : info3.data_file = r->data_file;
10186 0 : info3.config_file = r->config_file;
10187 0 : info3.help_file = r->help_file;
10188 0 : info3.monitor_name = r->monitor_name;
10189 0 : info3.default_datatype = r->default_datatype;
10190 0 : info3._ndr_size_dependent_files = r->_ndr_size_dependent_files;
10191 0 : info3.dependent_files = r->dependent_files;
10192 :
10193 0 : info_ctr.level = 3;
10194 0 : info_ctr.info.info3 = &info3;
10195 :
10196 0 : if (ex) {
10197 0 : torture_assert(tctx,
10198 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10199 : "failed to test AddPrinterDriverEx level 3");
10200 : } else {
10201 0 : torture_assert(tctx,
10202 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
10203 : "failed to test AddPrinterDriver level 3");
10204 : }
10205 :
10206 0 : torture_assert(tctx,
10207 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 3, r->driver_name, &info),
10208 : "failed to find added printer driver");
10209 :
10210 0 : if (remote_driver_dir) {
10211 0 : int i;
10212 0 : ASSERT_DRIVER_PATH(tctx, info.info3.driver_path, remote_driver_dir, "unexpected path");
10213 0 : ASSERT_DRIVER_PATH(tctx, info.info3.data_file, remote_driver_dir, "unexpected path");
10214 0 : ASSERT_DRIVER_PATH(tctx, info.info3.config_file, remote_driver_dir, "unexpected path");
10215 0 : ASSERT_DRIVER_PATH(tctx, info.info3.help_file, remote_driver_dir, "unexpected path");
10216 0 : for (i=0; info.info3.dependent_files && info.info3.dependent_files[i] != NULL; i++) {
10217 0 : ASSERT_DRIVER_PATH(tctx, info.info3.dependent_files[i], remote_driver_dir, "unexpected path");
10218 : }
10219 : }
10220 :
10221 0 : return true;
10222 : }
10223 :
10224 0 : static bool test_AddPrinterDriver_args_level_4(struct torture_context *tctx,
10225 : struct dcerpc_binding_handle *b,
10226 : const char *server_name,
10227 : struct spoolss_AddDriverInfo8 *r,
10228 : uint32_t flags,
10229 : bool ex,
10230 : const char *remote_driver_dir)
10231 : {
10232 0 : struct spoolss_AddDriverInfoCtr info_ctr;
10233 0 : struct spoolss_AddDriverInfo4 info4;
10234 0 : union spoolss_DriverInfo info;
10235 :
10236 0 : info4.version = r->version;
10237 0 : info4.driver_name = r->driver_name;
10238 0 : info4.architecture = r->architecture;
10239 0 : info4.driver_path = r->driver_path;
10240 0 : info4.data_file = r->data_file;
10241 0 : info4.config_file = r->config_file;
10242 0 : info4.help_file = r->help_file;
10243 0 : info4.monitor_name = r->monitor_name;
10244 0 : info4.default_datatype = r->default_datatype;
10245 0 : info4._ndr_size_dependent_files = r->_ndr_size_dependent_files;
10246 0 : info4.dependent_files = r->dependent_files;
10247 0 : info4._ndr_size_previous_names = r->_ndr_size_previous_names;
10248 0 : info4.previous_names = r->previous_names;
10249 :
10250 0 : info_ctr.level = 4;
10251 0 : info_ctr.info.info4 = &info4;
10252 :
10253 0 : if (ex) {
10254 0 : torture_assert(tctx,
10255 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10256 : "failed to test AddPrinterDriverEx level 4");
10257 : } else {
10258 0 : torture_assert(tctx,
10259 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
10260 : "failed to test AddPrinterDriver level 4");
10261 : }
10262 :
10263 0 : torture_assert(tctx,
10264 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 4, r->driver_name, &info),
10265 : "failed to find added printer driver");
10266 :
10267 0 : if (remote_driver_dir) {
10268 0 : int i;
10269 0 : ASSERT_DRIVER_PATH(tctx, info.info4.driver_path, remote_driver_dir, "unexpected path");
10270 0 : ASSERT_DRIVER_PATH(tctx, info.info4.data_file, remote_driver_dir, "unexpected path");
10271 0 : ASSERT_DRIVER_PATH(tctx, info.info4.config_file, remote_driver_dir, "unexpected path");
10272 0 : ASSERT_DRIVER_PATH(tctx, info.info4.help_file, remote_driver_dir, "unexpected path");
10273 0 : for (i=0; info.info4.dependent_files && info.info4.dependent_files[i] != NULL; i++) {
10274 0 : ASSERT_DRIVER_PATH(tctx, info.info4.dependent_files[i], remote_driver_dir, "unexpected path");
10275 : }
10276 : }
10277 :
10278 0 : return true;
10279 : }
10280 :
10281 0 : static bool test_AddPrinterDriver_args_level_6(struct torture_context *tctx,
10282 : struct dcerpc_binding_handle *b,
10283 : const char *server_name,
10284 : struct spoolss_AddDriverInfo8 *r,
10285 : uint32_t flags,
10286 : bool ex,
10287 : const char *remote_driver_dir)
10288 : {
10289 0 : struct spoolss_AddDriverInfoCtr info_ctr;
10290 0 : struct spoolss_AddDriverInfo6 info6;
10291 0 : union spoolss_DriverInfo info;
10292 :
10293 0 : info6.version = r->version;
10294 0 : info6.driver_name = r->driver_name;
10295 0 : info6.architecture = r->architecture;
10296 0 : info6.driver_path = r->driver_path;
10297 0 : info6.data_file = r->data_file;
10298 0 : info6.config_file = r->config_file;
10299 0 : info6.help_file = r->help_file;
10300 0 : info6.monitor_name = r->monitor_name;
10301 0 : info6.default_datatype = r->default_datatype;
10302 0 : info6._ndr_size_dependent_files = r->_ndr_size_dependent_files;
10303 0 : info6.dependent_files = r->dependent_files;
10304 0 : info6._ndr_size_previous_names = r->_ndr_size_previous_names;
10305 0 : info6.previous_names = r->previous_names;
10306 0 : info6.driver_date = r->driver_date;
10307 0 : info6.driver_version = r->driver_version;
10308 0 : info6.manufacturer_name = r->manufacturer_name;
10309 0 : info6.manufacturer_url = r->manufacturer_url;
10310 0 : info6.hardware_id = r->hardware_id;
10311 0 : info6.provider = r->provider;
10312 :
10313 0 : info_ctr.level = 6;
10314 0 : info_ctr.info.info6 = &info6;
10315 :
10316 0 : if (ex) {
10317 0 : torture_assert(tctx,
10318 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10319 : "failed to test AddPrinterDriverEx level 6");
10320 : } else {
10321 0 : torture_assert(tctx,
10322 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10323 : "failed to test AddPrinterDriver level 6");
10324 : }
10325 :
10326 : /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
10327 :
10328 0 : if (!ex) {
10329 0 : return true;
10330 : }
10331 :
10332 0 : torture_assert(tctx,
10333 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 6, r->driver_name, &info),
10334 : "failed to find added printer driver");
10335 :
10336 0 : if (remote_driver_dir) {
10337 0 : int i;
10338 0 : ASSERT_DRIVER_PATH(tctx, info.info6.driver_path, remote_driver_dir, "unexpected path");
10339 0 : ASSERT_DRIVER_PATH(tctx, info.info6.data_file, remote_driver_dir, "unexpected path");
10340 0 : ASSERT_DRIVER_PATH(tctx, info.info6.config_file, remote_driver_dir, "unexpected path");
10341 0 : ASSERT_DRIVER_PATH(tctx, info.info6.help_file, remote_driver_dir, "unexpected path");
10342 0 : for (i=0; info.info6.dependent_files && info.info6.dependent_files[i] != NULL; i++) {
10343 0 : ASSERT_DRIVER_PATH(tctx, info.info6.dependent_files[i], remote_driver_dir, "unexpected path");
10344 : }
10345 : }
10346 :
10347 0 : torture_assert_nttime_equal(tctx, info.info6.driver_date, info6.driver_date, "driverdate mismatch");
10348 0 : torture_assert_u64_equal(tctx, info.info6.driver_version, info6.driver_version, "driverversion mismatch");
10349 :
10350 0 : return true;
10351 : }
10352 :
10353 0 : static bool test_AddPrinterDriver_args_level_8(struct torture_context *tctx,
10354 : struct dcerpc_binding_handle *b,
10355 : const char *server_name,
10356 : struct spoolss_AddDriverInfo8 *r,
10357 : uint32_t flags,
10358 : bool ex,
10359 : const char *remote_driver_dir)
10360 : {
10361 0 : struct spoolss_AddDriverInfoCtr info_ctr;
10362 0 : union spoolss_DriverInfo info;
10363 :
10364 0 : info_ctr.level = 8;
10365 0 : info_ctr.info.info8 = r;
10366 :
10367 0 : if (ex) {
10368 0 : torture_assert(tctx,
10369 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10370 : "failed to test AddPrinterDriverEx level 8");
10371 : } else {
10372 0 : torture_assert(tctx,
10373 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10374 : "failed to test AddPrinterDriver level 8");
10375 : }
10376 :
10377 : /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
10378 :
10379 0 : if (!ex) {
10380 0 : return true;
10381 : }
10382 :
10383 0 : torture_assert(tctx,
10384 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 8, r->driver_name, &info),
10385 : "failed to find added printer driver");
10386 :
10387 0 : if (remote_driver_dir) {
10388 0 : int i;
10389 0 : ASSERT_DRIVER_PATH(tctx, info.info8.driver_path, remote_driver_dir, "unexpected path");
10390 0 : ASSERT_DRIVER_PATH(tctx, info.info8.data_file, remote_driver_dir, "unexpected path");
10391 0 : ASSERT_DRIVER_PATH(tctx, info.info8.config_file, remote_driver_dir, "unexpected path");
10392 0 : ASSERT_DRIVER_PATH(tctx, info.info8.help_file, remote_driver_dir, "unexpected path");
10393 0 : for (i=0; info.info8.dependent_files && info.info8.dependent_files[i] != NULL; i++) {
10394 0 : ASSERT_DRIVER_PATH(tctx, info.info8.dependent_files[i], remote_driver_dir, "unexpected path");
10395 : }
10396 : }
10397 :
10398 0 : torture_assert_nttime_equal(tctx, info.info8.driver_date, r->driver_date, "driverdate mismatch");
10399 0 : torture_assert_u64_equal(tctx, info.info8.driver_version, r->driver_version, "driverversion mismatch");
10400 :
10401 0 : return true;
10402 : }
10403 :
10404 : #undef ASSERT_DRIVER_PATH
10405 :
10406 0 : static bool test_DeletePrinterDriver_exp(struct torture_context *tctx,
10407 : struct dcerpc_binding_handle *b,
10408 : const char *server,
10409 : const char *driver,
10410 : const char *environment,
10411 : WERROR expected_result)
10412 : {
10413 0 : struct spoolss_DeletePrinterDriver r;
10414 :
10415 0 : r.in.server = server;
10416 0 : r.in.architecture = environment;
10417 0 : r.in.driver = driver;
10418 :
10419 0 : torture_comment(tctx, "Testing DeletePrinterDriver(%s)\n", driver);
10420 :
10421 0 : torture_assert_ntstatus_ok(tctx,
10422 : dcerpc_spoolss_DeletePrinterDriver_r(b, tctx, &r),
10423 : "DeletePrinterDriver failed");
10424 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
10425 : "DeletePrinterDriver failed with unexpected result");
10426 :
10427 0 : return true;
10428 : }
10429 :
10430 0 : static bool test_DeletePrinterDriverEx_exp(struct torture_context *tctx,
10431 : struct dcerpc_binding_handle *b,
10432 : const char *server,
10433 : const char *driver,
10434 : const char *environment,
10435 : uint32_t delete_flags,
10436 : uint32_t version,
10437 : WERROR expected_result)
10438 : {
10439 0 : struct spoolss_DeletePrinterDriverEx r;
10440 :
10441 0 : r.in.server = server;
10442 0 : r.in.architecture = environment;
10443 0 : r.in.driver = driver;
10444 0 : r.in.delete_flags = delete_flags;
10445 0 : r.in.version = version;
10446 :
10447 0 : torture_comment(tctx, "Testing DeletePrinterDriverEx(%s)\n", driver);
10448 :
10449 0 : torture_assert_ntstatus_ok(tctx,
10450 : dcerpc_spoolss_DeletePrinterDriverEx_r(b, tctx, &r),
10451 : "DeletePrinterDriverEx failed");
10452 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
10453 : "DeletePrinterDriverEx failed with unexpected result");
10454 :
10455 0 : return true;
10456 : }
10457 :
10458 0 : static bool test_DeletePrinterDriver(struct torture_context *tctx,
10459 : struct dcerpc_binding_handle *b,
10460 : const char *server_name,
10461 : const char *driver,
10462 : const char *environment)
10463 : {
10464 0 : torture_assert(tctx,
10465 : test_DeletePrinterDriver_exp(tctx, b, server_name, driver, "FOOBAR", WERR_INVALID_ENVIRONMENT),
10466 : "failed to delete driver");
10467 :
10468 0 : torture_assert(tctx,
10469 : test_DeletePrinterDriver_exp(tctx, b, server_name, driver, environment, WERR_OK),
10470 : "failed to delete driver");
10471 :
10472 0 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name, environment, 1, driver, NULL)) {
10473 0 : torture_fail(tctx, "deleted driver still enumerated");
10474 : }
10475 :
10476 0 : torture_assert(tctx,
10477 : test_DeletePrinterDriver_exp(tctx, b, server_name, driver, environment, WERR_UNKNOWN_PRINTER_DRIVER),
10478 : "2nd delete failed");
10479 :
10480 0 : return true;
10481 : }
10482 :
10483 0 : static bool test_DeletePrinterDriverEx(struct torture_context *tctx,
10484 : struct dcerpc_binding_handle *b,
10485 : const char *server_name,
10486 : const char *driver,
10487 : const char *environment,
10488 : uint32_t delete_flags,
10489 : uint32_t version)
10490 : {
10491 0 : torture_assert(tctx,
10492 : test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, "FOOBAR", delete_flags, version, WERR_INVALID_ENVIRONMENT),
10493 : "failed to delete driver");
10494 :
10495 0 : torture_assert(tctx,
10496 : test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, environment, delete_flags, version, WERR_OK),
10497 : "failed to delete driver");
10498 :
10499 0 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name, environment, 1, driver, NULL)) {
10500 0 : torture_fail(tctx, "deleted driver still enumerated");
10501 : }
10502 :
10503 0 : torture_assert(tctx,
10504 : test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, environment, delete_flags, version, WERR_UNKNOWN_PRINTER_DRIVER),
10505 : "2nd delete failed");
10506 :
10507 0 : return true;
10508 : }
10509 :
10510 0 : static bool test_PrinterDriver_args(struct torture_context *tctx,
10511 : struct dcerpc_binding_handle *b,
10512 : const char *server_name,
10513 : uint32_t level,
10514 : struct spoolss_AddDriverInfo8 *r,
10515 : uint32_t add_flags,
10516 : uint32_t delete_flags,
10517 : uint32_t delete_version,
10518 : bool ex,
10519 : const char *remote_driver_dir)
10520 : {
10521 0 : bool ret = true;
10522 :
10523 0 : switch (level) {
10524 0 : case 1:
10525 0 : ret = test_AddPrinterDriver_args_level_1(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10526 0 : break;
10527 0 : case 2:
10528 0 : ret = test_AddPrinterDriver_args_level_2(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10529 0 : break;
10530 0 : case 3:
10531 0 : ret = test_AddPrinterDriver_args_level_3(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10532 0 : break;
10533 0 : case 4:
10534 0 : ret = test_AddPrinterDriver_args_level_4(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10535 0 : break;
10536 0 : case 6:
10537 0 : ret = test_AddPrinterDriver_args_level_6(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10538 0 : break;
10539 0 : case 8:
10540 0 : ret = test_AddPrinterDriver_args_level_8(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10541 0 : break;
10542 0 : default:
10543 0 : return false;
10544 : }
10545 :
10546 0 : if (ret == false) {
10547 0 : return ret;
10548 : }
10549 :
10550 0 : if (level == 1) {
10551 0 : return ret;
10552 : }
10553 :
10554 : /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
10555 :
10556 0 : if (!ex && (level == 6 || level == 8)) {
10557 0 : return ret;
10558 : }
10559 :
10560 : {
10561 0 : struct dcerpc_pipe *p2;
10562 0 : struct policy_handle hive_handle;
10563 0 : struct dcerpc_binding_handle *b2;
10564 :
10565 0 : torture_assert_ntstatus_ok(tctx,
10566 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
10567 : "could not open winreg pipe");
10568 0 : b2 = p2->binding_handle;
10569 :
10570 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
10571 :
10572 0 : ret = test_GetDriverInfo_winreg(tctx, b, NULL, NULL, r->driver_name, r->architecture, r->version, b2, &hive_handle, server_name);
10573 :
10574 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
10575 :
10576 0 : talloc_free(p2);
10577 : }
10578 :
10579 0 : if (ex) {
10580 0 : return test_DeletePrinterDriverEx(tctx, b, server_name, r->driver_name, r->architecture, delete_flags, r->version);
10581 : } else {
10582 0 : return test_DeletePrinterDriver(tctx, b, server_name, r->driver_name, r->architecture);
10583 : }
10584 : }
10585 :
10586 64 : static bool fillup_printserver_info(struct torture_context *tctx,
10587 : struct dcerpc_pipe *p,
10588 : struct torture_driver_context *d)
10589 : {
10590 0 : struct policy_handle server_handle;
10591 64 : struct dcerpc_binding_handle *b = p->binding_handle;
10592 64 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
10593 :
10594 64 : torture_assert(tctx,
10595 : test_OpenPrinter_server(tctx, p, &server_handle),
10596 : "failed to open printserver");
10597 64 : torture_assert(tctx,
10598 : test_get_environment(tctx, b, &server_handle, &d->remote.environment),
10599 : "failed to get environment");
10600 64 : torture_assert(tctx,
10601 : test_ClosePrinter(tctx, b, &server_handle),
10602 : "failed to close printserver");
10603 :
10604 64 : torture_assert(tctx,
10605 : test_GetPrinterDriverDirectory_getdir(tctx, b, server_name_slash,
10606 : d->local.environment ? d->local.environment : d->remote.environment,
10607 : &d->remote.driver_directory),
10608 : "failed to get driver directory");
10609 :
10610 64 : return true;
10611 : }
10612 :
10613 0 : static const char *driver_directory_dir(const char *driver_directory)
10614 : {
10615 0 : char *p;
10616 :
10617 0 : p = strrchr(driver_directory, '\\');
10618 0 : if (p) {
10619 0 : return p+1;
10620 : }
10621 :
10622 0 : return NULL;
10623 : }
10624 :
10625 0 : static const char *driver_directory_share(struct torture_context *tctx,
10626 : const char *driver_directory)
10627 : {
10628 0 : const char *p;
10629 0 : char *tok;
10630 :
10631 0 : if (driver_directory[0] == '\\' && driver_directory[1] == '\\') {
10632 0 : driver_directory += 2;
10633 : }
10634 :
10635 0 : p = talloc_strdup(tctx, driver_directory);
10636 :
10637 0 : torture_assert(tctx,
10638 : next_token_talloc(tctx, &p, &tok, "\\"),
10639 : "cannot explode uri");
10640 0 : torture_assert(tctx,
10641 : next_token_talloc(tctx, &p, &tok, "\\"),
10642 : "cannot explode uri");
10643 :
10644 0 : return tok;
10645 : }
10646 :
10647 : #define CREATE_PRINTER_DRIVER_PATH(_d, _file) \
10648 : talloc_asprintf((_d), "%s\\%s\\%s", (_d)->remote.driver_directory, (_d)->remote.driver_upload_directory, (_file))
10649 :
10650 :
10651 0 : static bool create_printer_driver_directory(struct torture_context *tctx,
10652 : struct smbcli_state *cli,
10653 : struct torture_driver_context *d)
10654 : {
10655 0 : char *driver_dir;
10656 :
10657 0 : if (d->remote.driver_upload_directory == NULL) {
10658 0 : return true;
10659 : }
10660 :
10661 0 : driver_dir = talloc_asprintf(tctx,
10662 : "%s\\%s",
10663 : driver_directory_dir(d->remote.driver_directory),
10664 : d->remote.driver_upload_directory);
10665 0 : torture_assert_not_null(tctx, driver_dir, "ENOMEM");
10666 :
10667 0 : torture_comment(tctx,
10668 : "Create remote driver directory: %s\n",
10669 : driver_dir);
10670 :
10671 0 : torture_assert_ntstatus_ok(tctx,
10672 : smbcli_mkdir(cli->tree,
10673 : driver_dir),
10674 : "Failed to create driver directory");
10675 :
10676 0 : return true;
10677 : }
10678 :
10679 0 : static bool upload_printer_driver_file(struct torture_context *tctx,
10680 : struct smbcli_state *cli,
10681 : struct torture_driver_context *d,
10682 : const char *file_name)
10683 : {
10684 0 : FILE *f;
10685 0 : int fnum;
10686 0 : uint8_t *buf;
10687 0 : int maxwrite = 64512;
10688 0 : off_t nread = 0;
10689 0 : size_t start = 0;
10690 0 : const char *remote_dir = driver_directory_dir(d->remote.driver_directory);
10691 0 : const char *remote_name;
10692 0 : const char *local_name;
10693 0 : const char *p;
10694 :
10695 0 : if (!file_name || strlen(file_name) == 0) {
10696 0 : return true;
10697 : }
10698 :
10699 0 : p = strrchr(file_name, '\\');
10700 0 : if (p == NULL) {
10701 0 : p = file_name;
10702 : } else {
10703 0 : p++;
10704 : }
10705 :
10706 0 : local_name = talloc_asprintf(tctx, "%s/%s", d->local.driver_directory, p);
10707 0 : torture_assert_not_null(tctx, local_name, "ENOMEM");
10708 0 : if (d->remote.driver_upload_directory != NULL) {
10709 0 : remote_name = talloc_asprintf(tctx,
10710 : "%s\\%s\\%s",
10711 : remote_dir,
10712 : d->remote.driver_upload_directory,
10713 : p);
10714 : } else {
10715 0 : remote_name = talloc_asprintf(tctx, "%s\\%s", remote_dir, p);
10716 : }
10717 0 : torture_assert_not_null(tctx, remote_name, "ENOMEM");
10718 :
10719 0 : torture_comment(tctx, "Uploading %s to %s\n", local_name, remote_name);
10720 :
10721 0 : fnum = smbcli_open(cli->tree, remote_name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
10722 0 : if (fnum == -1) {
10723 0 : torture_fail(tctx, talloc_asprintf(tctx, "failed to open remote file: %s\n", remote_name));
10724 : }
10725 :
10726 0 : f = fopen(local_name, "r");
10727 0 : if (f == NULL) {
10728 0 : torture_fail(tctx, talloc_asprintf(tctx, "failed to open local file: %s\n", local_name));
10729 : }
10730 :
10731 0 : buf = talloc_array(tctx, uint8_t, maxwrite);
10732 0 : if (!buf) {
10733 0 : fclose(f);
10734 0 : return false;
10735 : }
10736 :
10737 0 : while (!feof(f)) {
10738 0 : int n = maxwrite;
10739 0 : int ret;
10740 :
10741 0 : if ((n = fread(buf, 1, n, f)) < 1) {
10742 0 : if((n == 0) && feof(f))
10743 0 : break; /* Empty local file. */
10744 :
10745 0 : torture_warning(tctx,
10746 0 : "failed to read file: %s\n", strerror(errno));
10747 0 : break;
10748 : }
10749 :
10750 0 : ret = smbcli_write(cli->tree, fnum, 0, buf, nread + start, n);
10751 :
10752 0 : if (n != ret) {
10753 0 : torture_warning(tctx,
10754 : "failed to write file: %s\n", smbcli_errstr(cli->tree));
10755 0 : break;
10756 : }
10757 :
10758 0 : nread += n;
10759 : }
10760 :
10761 0 : fclose(f);
10762 :
10763 0 : torture_assert_ntstatus_ok(tctx,
10764 : smbcli_close(cli->tree, fnum),
10765 : "failed to close file");
10766 :
10767 0 : return true;
10768 : }
10769 :
10770 0 : static bool connect_printer_driver_share(struct torture_context *tctx,
10771 : const char *server_name,
10772 : const char *share_name,
10773 : struct smbcli_state **cli)
10774 : {
10775 0 : struct smbcli_options smb_options;
10776 0 : struct smbcli_session_options smb_session_options;
10777 :
10778 0 : torture_comment(tctx, "Connecting printer driver share '%s' on '%s'\n",
10779 : share_name, server_name);
10780 :
10781 0 : lpcfg_smbcli_options(tctx->lp_ctx, &smb_options);
10782 0 : lpcfg_smbcli_session_options(tctx->lp_ctx, &smb_session_options);
10783 :
10784 0 : torture_assert_ntstatus_ok(tctx,
10785 : smbcli_full_connection(tctx, cli, server_name,
10786 : lpcfg_smb_ports(tctx->lp_ctx),
10787 : share_name, NULL,
10788 : lpcfg_socket_options(tctx->lp_ctx),
10789 : samba_cmdline_get_creds(),
10790 : lpcfg_resolve_context(tctx->lp_ctx),
10791 : tctx->ev,
10792 : &smb_options,
10793 : &smb_session_options,
10794 : lpcfg_gensec_settings(tctx, tctx->lp_ctx)),
10795 : "failed to open driver share");
10796 :
10797 0 : return true;
10798 : }
10799 :
10800 0 : static bool upload_printer_driver(struct torture_context *tctx,
10801 : const char *server_name,
10802 : struct torture_driver_context *d)
10803 : {
10804 0 : struct smbcli_state *cli;
10805 0 : const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
10806 0 : int i;
10807 :
10808 0 : torture_assert(tctx,
10809 : connect_printer_driver_share(tctx, server_name, share_name, &cli),
10810 : "failed to connect to driver share");
10811 :
10812 0 : torture_comment(tctx, "Uploading printer driver files to \\\\%s\\%s\n",
10813 : server_name, share_name);
10814 :
10815 0 : torture_assert(tctx,
10816 : create_printer_driver_directory(tctx, cli, d),
10817 : "failed to create driver directory");
10818 :
10819 0 : torture_assert(tctx,
10820 : upload_printer_driver_file(tctx, cli, d, d->info8.driver_path),
10821 : "failed to upload driver_path");
10822 0 : torture_assert(tctx,
10823 : upload_printer_driver_file(tctx, cli, d, d->info8.data_file),
10824 : "failed to upload data_file");
10825 0 : torture_assert(tctx,
10826 : upload_printer_driver_file(tctx, cli, d, d->info8.config_file),
10827 : "failed to upload config_file");
10828 0 : torture_assert(tctx,
10829 : upload_printer_driver_file(tctx, cli, d, d->info8.help_file),
10830 : "failed to upload help_file");
10831 0 : if (d->info8.dependent_files) {
10832 0 : for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
10833 0 : torture_assert(tctx,
10834 : upload_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]),
10835 : "failed to upload dependent_files");
10836 : }
10837 : }
10838 :
10839 0 : talloc_free(cli);
10840 :
10841 0 : return true;
10842 : }
10843 :
10844 0 : static bool check_printer_driver_file(struct torture_context *tctx,
10845 : struct smbcli_state *cli,
10846 : struct torture_driver_context *d,
10847 : const char *file_name)
10848 : {
10849 0 : const char *remote_arch_dir = driver_directory_dir(d->remote.driver_directory);
10850 0 : const char *remote_name = talloc_asprintf(tctx, "%s\\%d\\%s",
10851 : remote_arch_dir,
10852 0 : d->info8.version,
10853 : file_name);
10854 0 : int fnum;
10855 :
10856 0 : torture_assert(tctx, (file_name && strlen(file_name) != 0), "invalid filename");
10857 :
10858 0 : torture_comment(tctx, "checking for driver file at %s\n", remote_name);
10859 :
10860 0 : fnum = smbcli_open(cli->tree, remote_name, O_RDONLY, DENY_NONE);
10861 0 : if (fnum == -1) {
10862 0 : return false;
10863 : }
10864 :
10865 0 : torture_assert_ntstatus_ok(tctx,
10866 : smbcli_close(cli->tree, fnum),
10867 : "failed to close driver file");
10868 :
10869 0 : return true;
10870 : }
10871 :
10872 0 : static bool check_printer_driver_files(struct torture_context *tctx,
10873 : const char *server_name,
10874 : struct torture_driver_context *d,
10875 : bool expect_exist)
10876 : {
10877 0 : struct smbcli_state *cli;
10878 0 : const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
10879 0 : int i;
10880 :
10881 0 : torture_assert(tctx,
10882 : connect_printer_driver_share(tctx, server_name, share_name, &cli),
10883 : "failed to connect to driver share");
10884 :
10885 0 : torture_comment(tctx, "checking %sexistent driver files at \\\\%s\\%s\n",
10886 : (expect_exist ? "": "non-"),
10887 : server_name, share_name);
10888 :
10889 0 : if (d->info8.driver_path && d->info8.driver_path[0]) {
10890 0 : torture_assert(tctx,
10891 : check_printer_driver_file(tctx, cli, d, d->info8.driver_path) == expect_exist,
10892 : "failed driver_path check");
10893 : }
10894 0 : if (d->info8.data_file && d->info8.data_file[0]) {
10895 0 : torture_assert(tctx,
10896 : check_printer_driver_file(tctx, cli, d, d->info8.data_file) == expect_exist,
10897 : "failed data_file check");
10898 : }
10899 0 : if (d->info8.config_file && d->info8.config_file[0]) {
10900 0 : torture_assert(tctx,
10901 : check_printer_driver_file(tctx, cli, d, d->info8.config_file) == expect_exist,
10902 : "failed config_file check");
10903 : }
10904 0 : if (d->info8.help_file && d->info8.help_file[0]) {
10905 0 : torture_assert(tctx,
10906 : check_printer_driver_file(tctx, cli, d, d->info8.help_file) == expect_exist,
10907 : "failed help_file check");
10908 : }
10909 0 : if (d->info8.dependent_files) {
10910 0 : for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
10911 0 : torture_assert(tctx,
10912 : check_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]) == expect_exist,
10913 : "failed dependent_files check");
10914 : }
10915 : }
10916 :
10917 0 : talloc_free(cli);
10918 :
10919 0 : return true;
10920 : }
10921 :
10922 0 : static bool remove_printer_driver_file(struct torture_context *tctx,
10923 : struct smbcli_state *cli,
10924 : struct torture_driver_context *d,
10925 : const char *file_name)
10926 : {
10927 0 : const char *remote_name;
10928 0 : const char *remote_dir = driver_directory_dir(d->remote.driver_directory);
10929 :
10930 0 : if (!file_name || strlen(file_name) == 0) {
10931 0 : return true;
10932 : }
10933 :
10934 0 : remote_name = talloc_asprintf(tctx, "%s\\%s", remote_dir, file_name);
10935 :
10936 0 : torture_comment(tctx, "Removing %s\n", remote_name);
10937 :
10938 0 : torture_assert_ntstatus_ok(tctx,
10939 : smbcli_unlink(cli->tree, remote_name),
10940 : "failed to unlink");
10941 :
10942 0 : return true;
10943 : }
10944 :
10945 0 : static bool remove_printer_driver(struct torture_context *tctx,
10946 : const char *server_name,
10947 : struct torture_driver_context *d)
10948 : {
10949 0 : struct smbcli_state *cli;
10950 0 : const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
10951 0 : int i;
10952 :
10953 0 : torture_assert(tctx,
10954 : connect_printer_driver_share(tctx, server_name, share_name, &cli),
10955 : "failed to connect to driver share");
10956 :
10957 0 : torture_comment(tctx, "Removing printer driver files from \\\\%s\\%s\n",
10958 : server_name, share_name);
10959 :
10960 0 : torture_assert(tctx,
10961 : remove_printer_driver_file(tctx, cli, d, d->info8.driver_path),
10962 : "failed to remove driver_path");
10963 0 : torture_assert(tctx,
10964 : remove_printer_driver_file(tctx, cli, d, d->info8.data_file),
10965 : "failed to remove data_file");
10966 0 : if (!strequal(d->info8.config_file, d->info8.driver_path)) {
10967 0 : torture_assert(tctx,
10968 : remove_printer_driver_file(tctx, cli, d, d->info8.config_file),
10969 : "failed to remove config_file");
10970 : }
10971 0 : torture_assert(tctx,
10972 : remove_printer_driver_file(tctx, cli, d, d->info8.help_file),
10973 : "failed to remove help_file");
10974 0 : if (d->info8.dependent_files) {
10975 0 : for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
10976 0 : if (strequal(d->info8.dependent_files->string[i], d->info8.driver_path) ||
10977 0 : strequal(d->info8.dependent_files->string[i], d->info8.data_file) ||
10978 0 : strequal(d->info8.dependent_files->string[i], d->info8.config_file) ||
10979 0 : strequal(d->info8.dependent_files->string[i], d->info8.help_file)) {
10980 0 : continue;
10981 : }
10982 0 : torture_assert(tctx,
10983 : remove_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]),
10984 : "failed to remove dependent_files");
10985 : }
10986 : }
10987 :
10988 0 : talloc_free(cli);
10989 :
10990 0 : return true;
10991 :
10992 : }
10993 :
10994 32 : static bool test_add_driver_arg(struct torture_context *tctx,
10995 : struct dcerpc_pipe *p,
10996 : struct torture_driver_context *d)
10997 : {
10998 32 : bool ret = true;
10999 32 : struct dcerpc_binding_handle *b = p->binding_handle;
11000 32 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11001 32 : uint32_t levels[] = { 1, 2, 3, 4, 6, 8 };
11002 0 : int i;
11003 0 : struct spoolss_AddDriverInfo8 info8;
11004 32 : uint32_t add_flags = APD_COPY_NEW_FILES;
11005 32 : uint32_t delete_flags = 0;
11006 :
11007 32 : ZERO_STRUCT(info8);
11008 :
11009 32 : torture_comment(tctx, "Testing PrinterDriver%s '%s' for environment '%s'\n",
11010 32 : d->ex ? "Ex" : "", d->info8.driver_name, d->local.environment);
11011 :
11012 32 : torture_assert(tctx,
11013 : fillup_printserver_info(tctx, p, d),
11014 : "failed to fillup printserver info");
11015 :
11016 32 : if (!directory_exist(d->local.driver_directory)) {
11017 32 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11018 : }
11019 :
11020 0 : torture_assert(tctx,
11021 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11022 : "failed to upload printer driver");
11023 :
11024 0 : info8 = d->info8;
11025 0 : if (d->info8.dependent_files) {
11026 0 : info8.dependent_files = talloc_zero(tctx, struct spoolss_StringArray);
11027 0 : if (d->info8.dependent_files->string) {
11028 0 : for (i=0; d->info8.dependent_files->string[i] != NULL; i++) {
11029 0 : }
11030 0 : info8.dependent_files->string = talloc_zero_array(info8.dependent_files, const char *, i+1);
11031 0 : for (i=0; d->info8.dependent_files->string[i] != NULL; i++) {
11032 0 : info8.dependent_files->string[i] = talloc_strdup(info8.dependent_files->string, d->info8.dependent_files->string[i]);
11033 : }
11034 : }
11035 : }
11036 :
11037 0 : for (i=0; i < ARRAY_SIZE(levels); i++) {
11038 :
11039 0 : if (torture_setting_bool(tctx, "samba3", false)) {
11040 0 : switch (levels[i]) {
11041 0 : case 2:
11042 : case 4:
11043 0 : torture_comment(tctx, "skipping level %d against samba\n", levels[i]);
11044 0 : continue;
11045 0 : default:
11046 0 : break;
11047 : }
11048 : }
11049 0 : if (torture_setting_bool(tctx, "w2k3", false)) {
11050 0 : switch (levels[i]) {
11051 0 : case 8:
11052 0 : torture_comment(tctx, "skipping level %d against w2k3\n", levels[i]);
11053 0 : continue;
11054 0 : default:
11055 0 : break;
11056 : }
11057 : }
11058 :
11059 0 : torture_comment(tctx,
11060 : "Testing PrinterDriver%s '%s' add & delete level %d\n",
11061 0 : d->ex ? "Ex" : "", info8.driver_name, levels[i]);
11062 :
11063 0 : ret &= test_PrinterDriver_args(tctx, b, server_name_slash, levels[i], &info8, add_flags, delete_flags, d->info8.version, d->ex, d->remote.driver_directory);
11064 : }
11065 :
11066 0 : info8.driver_path = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.driver_path);
11067 0 : info8.data_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.data_file);
11068 0 : if (d->info8.config_file) {
11069 0 : info8.config_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.config_file);
11070 : }
11071 0 : if (d->info8.help_file) {
11072 0 : info8.help_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.help_file);
11073 : }
11074 0 : if (d->info8.dependent_files && d->info8.dependent_files->string) {
11075 0 : for (i=0; d->info8.dependent_files->string[i] != NULL; i++) {
11076 0 : info8.dependent_files->string[i] = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.dependent_files->string[i]);
11077 : }
11078 : }
11079 :
11080 0 : for (i=0; i < ARRAY_SIZE(levels); i++) {
11081 :
11082 0 : if (torture_setting_bool(tctx, "samba3", false)) {
11083 0 : switch (levels[i]) {
11084 0 : case 2:
11085 : case 4:
11086 0 : continue;
11087 0 : default:
11088 0 : break;
11089 : }
11090 : }
11091 0 : if (torture_setting_bool(tctx, "w2k3", false)) {
11092 0 : switch (levels[i]) {
11093 0 : case 8:
11094 0 : torture_comment(tctx, "skipping level %d against w2k3\n", levels[i]);
11095 0 : continue;
11096 0 : default:
11097 0 : break;
11098 : }
11099 : }
11100 :
11101 0 : torture_comment(tctx,
11102 : "Testing PrinterDriver%s '%s' add & delete level %d (full unc paths)\n",
11103 0 : d->ex ? "Ex" : "", info8.driver_name, levels[i]);
11104 :
11105 0 : ret &= test_PrinterDriver_args(tctx, b, server_name_slash, levels[i], &info8, add_flags, delete_flags, d->info8.version, d->ex, d->remote.driver_directory);
11106 : }
11107 :
11108 0 : torture_assert(tctx,
11109 : remove_printer_driver(tctx, dcerpc_server_name(p), d),
11110 : "failed to remove printer driver");
11111 :
11112 0 : torture_comment(tctx, "\n");
11113 :
11114 0 : return ret;
11115 : }
11116 :
11117 4 : static bool test_add_driver_ex_64(struct torture_context *tctx,
11118 : struct dcerpc_pipe *p)
11119 : {
11120 0 : struct torture_driver_context *d;
11121 :
11122 4 : d = talloc_zero(tctx, struct torture_driver_context);
11123 :
11124 4 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_x64);
11125 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
11126 :
11127 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11128 4 : d->info8.driver_name = TORTURE_DRIVER_EX;
11129 4 : d->info8.architecture = d->local.environment;
11130 4 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11131 4 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11132 4 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11133 4 : d->ex = true;
11134 :
11135 4 : return test_add_driver_arg(tctx, p, d);
11136 : }
11137 :
11138 4 : static bool test_add_driver_ex_32(struct torture_context *tctx,
11139 : struct dcerpc_pipe *p)
11140 : {
11141 0 : struct torture_driver_context *d;
11142 :
11143 4 : d = talloc_zero(tctx, struct torture_driver_context);
11144 :
11145 4 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11146 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11147 :
11148 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11149 4 : d->info8.driver_name = TORTURE_DRIVER_EX;
11150 4 : d->info8.architecture = d->local.environment;
11151 4 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11152 4 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11153 4 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11154 4 : d->ex = true;
11155 :
11156 4 : return test_add_driver_arg(tctx, p, d);
11157 : }
11158 :
11159 4 : static bool test_add_driver_64(struct torture_context *tctx,
11160 : struct dcerpc_pipe *p)
11161 : {
11162 0 : struct torture_driver_context *d;
11163 :
11164 4 : d = talloc_zero(tctx, struct torture_driver_context);
11165 :
11166 4 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_x64);
11167 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
11168 :
11169 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11170 4 : d->info8.driver_name = TORTURE_DRIVER_ADD;
11171 4 : d->info8.architecture = d->local.environment;
11172 4 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11173 4 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11174 4 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11175 4 : d->ex = false;
11176 :
11177 4 : return test_add_driver_arg(tctx, p, d);
11178 : }
11179 :
11180 4 : static bool test_add_driver_32(struct torture_context *tctx,
11181 : struct dcerpc_pipe *p)
11182 : {
11183 0 : struct torture_driver_context *d;
11184 :
11185 4 : d = talloc_zero(tctx, struct torture_driver_context);
11186 :
11187 4 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11188 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11189 :
11190 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11191 4 : d->info8.driver_name = TORTURE_DRIVER_ADD;
11192 4 : d->info8.architecture = d->local.environment;
11193 4 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11194 4 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11195 4 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11196 4 : d->ex = false;
11197 :
11198 4 : return test_add_driver_arg(tctx, p, d);
11199 : }
11200 :
11201 4 : static bool test_add_driver_adobe(struct torture_context *tctx,
11202 : struct dcerpc_pipe *p)
11203 : {
11204 0 : struct torture_driver_context *d;
11205 :
11206 4 : if (!torture_setting_bool(tctx, "samba3", false)) {
11207 0 : torture_skip(tctx, "skipping adobe test which only works against samba3");
11208 : }
11209 :
11210 4 : d = talloc_zero(tctx, struct torture_driver_context);
11211 :
11212 4 : d->local.environment = talloc_strdup(d, "Windows 4.0");
11213 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
11214 :
11215 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
11216 4 : d->info8.driver_name = TORTURE_DRIVER_ADOBE;
11217 4 : d->info8.architecture = d->local.environment;
11218 4 : d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
11219 4 : d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
11220 4 : d->info8.config_file = talloc_strdup(d, "ADOBEPS4.DRV");
11221 : #if 0
11222 : d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
11223 : d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
11224 : #endif
11225 4 : d->ex = false;
11226 :
11227 4 : return test_add_driver_arg(tctx, p, d);
11228 : }
11229 :
11230 4 : static bool test_add_driver_adobe_cupsaddsmb(struct torture_context *tctx,
11231 : struct dcerpc_pipe *p)
11232 : {
11233 0 : struct torture_driver_context *d;
11234 0 : struct spoolss_StringArray *a;
11235 :
11236 4 : if (!torture_setting_bool(tctx, "samba3", false)) {
11237 0 : torture_skip(tctx, "skipping cupsaddsmb test which only works against samba3");
11238 : }
11239 :
11240 4 : d = talloc_zero(tctx, struct torture_driver_context);
11241 :
11242 4 : d->local.environment = talloc_strdup(d, "Windows 4.0");
11243 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
11244 :
11245 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
11246 4 : d->info8.driver_name = TORTURE_DRIVER_ADOBE_CUPSADDSMB;
11247 4 : d->info8.architecture = d->local.environment;
11248 4 : d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
11249 4 : d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
11250 4 : d->info8.config_file = NULL;
11251 4 : d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
11252 4 : d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
11253 4 : d->info8.default_datatype = talloc_strdup(d, "RAW");
11254 :
11255 4 : a = talloc_zero(d, struct spoolss_StringArray);
11256 4 : a->string = talloc_zero_array(a, const char *, 7);
11257 4 : a->string[0] = talloc_strdup(a->string, "ADOBEPS4.DRV");
11258 4 : a->string[1] = talloc_strdup(a->string, "DEFPRTR2.PPD");
11259 4 : a->string[2] = talloc_strdup(a->string, "ADOBEPS4.HLP");
11260 4 : a->string[3] = talloc_strdup(a->string, "PSMON.DLL");
11261 4 : a->string[4] = talloc_strdup(a->string, "ADFONTS.MFM");
11262 4 : a->string[5] = talloc_strdup(a->string, "ICONLIB.DLL");
11263 :
11264 4 : d->info8.dependent_files = a;
11265 4 : d->ex = false;
11266 :
11267 4 : return test_add_driver_arg(tctx, p, d);
11268 : }
11269 :
11270 4 : static bool test_add_driver_timestamps(struct torture_context *tctx,
11271 : struct dcerpc_pipe *p)
11272 : {
11273 0 : struct torture_driver_context *d;
11274 4 : struct timeval t = timeval_current();
11275 :
11276 4 : d = talloc_zero(tctx, struct torture_driver_context);
11277 :
11278 4 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11279 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11280 :
11281 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11282 4 : d->info8.driver_name = TORTURE_DRIVER_TIMESTAMPS;
11283 4 : d->info8.architecture = d->local.environment;
11284 4 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11285 4 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11286 4 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11287 4 : d->info8.driver_date = timeval_to_nttime(&t);
11288 4 : d->ex = true;
11289 :
11290 4 : torture_assert(tctx,
11291 : test_add_driver_arg(tctx, p, d),
11292 : "");
11293 :
11294 4 : unix_to_nt_time(&d->info8.driver_date, 1);
11295 :
11296 4 : torture_assert(tctx,
11297 : test_add_driver_arg(tctx, p, d),
11298 : "");
11299 :
11300 4 : return true;
11301 : }
11302 :
11303 4 : static bool test_multiple_drivers(struct torture_context *tctx,
11304 : struct dcerpc_pipe *p)
11305 : {
11306 0 : struct torture_driver_context *d;
11307 4 : struct dcerpc_binding_handle *b = p->binding_handle;
11308 4 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11309 0 : int i;
11310 0 : struct spoolss_AddDriverInfo8 info8;
11311 4 : uint32_t add_flags = APD_COPY_NEW_FILES;
11312 4 : uint32_t delete_flags = 0;
11313 :
11314 4 : d = talloc_zero(tctx, struct torture_driver_context);
11315 :
11316 4 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11317 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11318 :
11319 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11320 4 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11321 4 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11322 4 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11323 4 : d->info8.architecture = d->local.environment;
11324 4 : d->ex = true;
11325 :
11326 4 : torture_assert(tctx,
11327 : fillup_printserver_info(tctx, p, d),
11328 : "failed to fillup printserver info");
11329 :
11330 4 : if (!directory_exist(d->local.driver_directory)) {
11331 4 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11332 : }
11333 :
11334 0 : torture_assert(tctx,
11335 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11336 : "failed to upload printer driver");
11337 :
11338 0 : info8 = d->info8;
11339 :
11340 0 : for (i=0; i < 3; i++) {
11341 0 : info8.driver_name = talloc_asprintf(d, "torture_test_driver_%d", i);
11342 :
11343 0 : torture_assert(tctx,
11344 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &info8, add_flags, true, NULL),
11345 : "failed to add driver");
11346 : }
11347 :
11348 0 : torture_assert(tctx,
11349 : test_DeletePrinterDriverEx(tctx, b, server_name_slash, "torture_test_driver_0", info8.architecture, delete_flags, info8.version),
11350 : "failed to delete driver");
11351 :
11352 0 : torture_assert(tctx,
11353 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, info8.architecture, 3, "torture_test_driver_1", NULL),
11354 : "torture_test_driver_1 no longer on the server");
11355 :
11356 0 : torture_assert(tctx,
11357 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, info8.architecture, 3, "torture_test_driver_2", NULL),
11358 : "torture_test_driver_2 no longer on the server");
11359 :
11360 0 : torture_assert(tctx,
11361 : test_DeletePrinterDriverEx(tctx, b, server_name_slash, "torture_test_driver_1", info8.architecture, delete_flags, info8.version),
11362 : "failed to delete driver");
11363 :
11364 0 : torture_assert(tctx,
11365 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, info8.architecture, 3, "torture_test_driver_2", NULL),
11366 : "torture_test_driver_2 no longer on the server");
11367 :
11368 0 : torture_assert(tctx,
11369 : test_DeletePrinterDriverEx(tctx, b, server_name_slash, "torture_test_driver_2", info8.architecture, delete_flags, info8.version),
11370 : "failed to delete driver");
11371 :
11372 0 : torture_assert(tctx,
11373 : remove_printer_driver(tctx, dcerpc_server_name(p), d),
11374 : "failed to remove printer driver");
11375 :
11376 0 : return true;
11377 : }
11378 :
11379 8 : static bool test_driver_copy_from_directory(struct torture_context *tctx,
11380 : struct dcerpc_pipe *p,
11381 : const char *architecture)
11382 : {
11383 0 : struct torture_driver_context *d;
11384 0 : struct spoolss_StringArray *a;
11385 8 : uint32_t add_flags = APD_COPY_NEW_FILES|APD_COPY_FROM_DIRECTORY|APD_RETURN_BLOCKING_STATUS_CODE;
11386 8 : uint32_t delete_flags = DPD_DELETE_ALL_FILES;
11387 8 : struct dcerpc_binding_handle *b = p->binding_handle;
11388 8 : const char *server_name_slash = talloc_asprintf(tctx,
11389 : "\\\\%s",
11390 : dcerpc_server_name(p));
11391 8 : struct GUID guid = GUID_random();
11392 8 : bool ok = false;
11393 :
11394 8 : d = talloc_zero(tctx, struct torture_driver_context);
11395 8 : torture_assert_not_null(tctx, d, "ENOMEM");
11396 :
11397 8 : d->local.environment = talloc_strdup(d, architecture);
11398 8 : torture_assert_not_null_goto(tctx, d->local.environment, ok, done, "ENOMEM");
11399 :
11400 8 : if (strequal(architecture, SPOOLSS_ARCHITECTURE_x64)) {
11401 4 : d->local.driver_directory =
11402 4 : talloc_strdup(d, "/usr/share/cups/drivers/x64");
11403 : } else {
11404 4 : d->local.driver_directory =
11405 4 : talloc_strdup(d, "/usr/share/cups/drivers/i386");
11406 : }
11407 8 : torture_assert_not_null_goto(tctx, d->local.driver_directory, ok, done, "ENOMEM");
11408 :
11409 8 : d->remote.driver_upload_directory = GUID_string2(d, &guid);
11410 8 : torture_assert_not_null_goto(tctx, d->remote.driver_upload_directory, ok, done, "ENOMEM");
11411 :
11412 8 : torture_assert(tctx,
11413 : fillup_printserver_info(tctx, p, d),
11414 : "failed to fillup printserver info");
11415 :
11416 8 : d->ex = true;
11417 8 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11418 8 : d->info8.driver_name = TORTURE_DRIVER_COPY_DIR;
11419 8 : d->info8.architecture = d->local.environment;
11420 :
11421 8 : d->info8.driver_path = CREATE_PRINTER_DRIVER_PATH(d, "pscript5.dll");
11422 8 : torture_assert_not_null_goto(tctx, d->info8.driver_path, ok, done, "ENOMEM");
11423 8 : d->info8.data_file = CREATE_PRINTER_DRIVER_PATH(d, "cups6.ppd");
11424 8 : torture_assert_not_null_goto(tctx, d->info8.data_file, ok, done, "ENOMEM");
11425 8 : d->info8.config_file = CREATE_PRINTER_DRIVER_PATH(d, "cupsui6.dll");
11426 8 : torture_assert_not_null_goto(tctx, d->info8.config_file, ok, done, "ENOMEM");
11427 8 : d->info8.help_file = CREATE_PRINTER_DRIVER_PATH(d, "pscript.hlp");
11428 8 : torture_assert_not_null_goto(tctx, d->info8.help_file, ok, done, "ENOMEM");
11429 :
11430 8 : a = talloc_zero(d, struct spoolss_StringArray);
11431 8 : torture_assert_not_null_goto(tctx, a, ok, done, "ENOMEM");
11432 8 : a->string = talloc_zero_array(a, const char *, 3);
11433 8 : torture_assert_not_null_goto(tctx, a->string, ok, done, "ENOMEM");
11434 8 : a->string[0] = CREATE_PRINTER_DRIVER_PATH(d, "cups6.inf");
11435 8 : torture_assert_not_null_goto(tctx, a->string[0], ok, done, "ENOMEM");
11436 8 : a->string[1] = CREATE_PRINTER_DRIVER_PATH(d, "cups6.ini");
11437 8 : torture_assert_not_null_goto(tctx, a->string[1], ok, done, "ENOMEM");
11438 :
11439 8 : d->info8.dependent_files = a;
11440 :
11441 8 : if (!directory_exist(d->local.driver_directory)) {
11442 8 : torture_skip(tctx,
11443 : "Skipping Printer Driver test as no local drivers "
11444 : "are available");
11445 : }
11446 :
11447 0 : torture_assert(tctx,
11448 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11449 : "failed to upload printer driver");
11450 :
11451 0 : torture_assert(tctx,
11452 : test_AddPrinterDriver_args_level_3(tctx,
11453 : b,
11454 : server_name_slash,
11455 : &d->info8,
11456 : add_flags,
11457 : true,
11458 : NULL),
11459 : "failed to add driver");
11460 :
11461 0 : torture_assert(tctx,
11462 : test_DeletePrinterDriverEx(tctx,
11463 : b,
11464 : server_name_slash,
11465 : d->info8.driver_name,
11466 : d->local.environment,
11467 : delete_flags,
11468 : d->info8.version),
11469 : "failed to delete driver");
11470 :
11471 0 : torture_assert(tctx,
11472 : check_printer_driver_files(tctx,
11473 : dcerpc_server_name(p),
11474 : d,
11475 : false),
11476 : "printer driver file check failed");
11477 :
11478 0 : ok = true;
11479 0 : done:
11480 0 : talloc_free(d);
11481 0 : return ok;
11482 : }
11483 :
11484 4 : static bool test_driver_copy_from_directory_64(struct torture_context *tctx,
11485 : struct dcerpc_pipe *p)
11486 : {
11487 4 : return test_driver_copy_from_directory(tctx, p, SPOOLSS_ARCHITECTURE_x64);
11488 : }
11489 :
11490 4 : static bool test_driver_copy_from_directory_32(struct torture_context *tctx,
11491 : struct dcerpc_pipe *p)
11492 : {
11493 4 : return test_driver_copy_from_directory(tctx, p, SPOOLSS_ARCHITECTURE_NT_X86);
11494 : }
11495 :
11496 4 : static bool test_del_driver_all_files(struct torture_context *tctx,
11497 : struct dcerpc_pipe *p)
11498 : {
11499 0 : struct torture_driver_context *d;
11500 0 : struct spoolss_StringArray *a;
11501 4 : uint32_t add_flags = APD_COPY_NEW_FILES;
11502 4 : uint32_t delete_flags = DPD_DELETE_ALL_FILES;
11503 4 : struct dcerpc_binding_handle *b = p->binding_handle;
11504 4 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11505 :
11506 4 : d = talloc_zero(tctx, struct torture_driver_context);
11507 :
11508 4 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_x64);
11509 4 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
11510 :
11511 4 : d->ex = true;
11512 4 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11513 4 : d->info8.driver_name = TORTURE_DRIVER_DELETER;
11514 4 : d->info8.architecture = d->local.environment;
11515 4 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11516 4 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11517 4 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11518 4 : d->info8.help_file = talloc_strdup(d, "pscript.hlp");
11519 :
11520 4 : a = talloc_zero(d, struct spoolss_StringArray);
11521 4 : a->string = talloc_zero_array(a, const char *, 3);
11522 4 : a->string[0] = talloc_strdup(a->string, "cups6.inf");
11523 4 : a->string[1] = talloc_strdup(a->string, "cups6.ini");
11524 :
11525 4 : d->info8.dependent_files = a;
11526 :
11527 4 : torture_assert(tctx,
11528 : fillup_printserver_info(tctx, p, d),
11529 : "failed to fillup printserver info");
11530 :
11531 4 : if (!directory_exist(d->local.driver_directory)) {
11532 4 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11533 : }
11534 :
11535 0 : torture_assert(tctx,
11536 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11537 : "failed to upload printer driver");
11538 :
11539 0 : torture_assert(tctx,
11540 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &d->info8, add_flags, true, NULL),
11541 : "failed to add driver");
11542 :
11543 0 : torture_assert(tctx,
11544 : test_DeletePrinterDriverEx(tctx, b, server_name_slash,
11545 : d->info8.driver_name,
11546 : d->info8.architecture,
11547 : delete_flags,
11548 : d->info8.version),
11549 : "failed to delete driver");
11550 :
11551 0 : torture_assert(tctx,
11552 : check_printer_driver_files(tctx, dcerpc_server_name(p), d, false),
11553 : "printer driver file check failed");
11554 :
11555 0 : talloc_free(d);
11556 0 : return true;
11557 : }
11558 :
11559 4 : static bool test_del_driver_unused_files(struct torture_context *tctx,
11560 : struct dcerpc_pipe *p)
11561 : {
11562 0 : struct torture_driver_context *d1;
11563 0 : struct torture_driver_context *d2;
11564 4 : uint32_t add_flags = APD_COPY_NEW_FILES;
11565 4 : struct dcerpc_binding_handle *b = p->binding_handle;
11566 4 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11567 :
11568 4 : d1 = talloc_zero(tctx, struct torture_driver_context);
11569 4 : d1->ex = true;
11570 :
11571 4 : d1->local.environment = talloc_strdup(d1, SPOOLSS_ARCHITECTURE_x64);
11572 4 : d1->local.driver_directory = talloc_strdup(d1, "/usr/share/cups/drivers/x64");
11573 :
11574 4 : d1->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11575 4 : d1->info8.driver_name = TORTURE_DRIVER_DELETER;
11576 4 : d1->info8.architecture = NULL;
11577 4 : d1->info8.driver_path = talloc_strdup(d1, "pscript5.dll");
11578 4 : d1->info8.data_file = talloc_strdup(d1, "cups6.ppd");
11579 4 : d1->info8.config_file = talloc_strdup(d1, "cupsui6.dll");
11580 4 : d1->info8.help_file = talloc_strdup(d1, "pscript.hlp");
11581 4 : d1->info8.architecture = d1->local.environment;
11582 :
11583 4 : d2 = talloc_zero(tctx, struct torture_driver_context);
11584 4 : d2->ex = true;
11585 :
11586 4 : d2->local.environment = talloc_strdup(d2, SPOOLSS_ARCHITECTURE_x64);
11587 4 : d2->local.driver_directory = talloc_strdup(d2, "/usr/share/cups/drivers/x64");
11588 :
11589 4 : d2->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11590 4 : d2->info8.driver_name = TORTURE_DRIVER_DELETERIN;
11591 4 : d2->info8.architecture = NULL;
11592 4 : d2->info8.driver_path = talloc_strdup(d2, "pscript5.dll"); /* overlapping */
11593 4 : d2->info8.data_file = talloc_strdup(d2, "cupsps6.dll");
11594 4 : d2->info8.config_file = talloc_strdup(d2, "cups6.ini");
11595 4 : d2->info8.help_file = talloc_strdup(d2, "pscript.hlp"); /* overlapping */
11596 4 : d2->info8.architecture = d2->local.environment;
11597 :
11598 4 : torture_assert(tctx,
11599 : fillup_printserver_info(tctx, p, d1),
11600 : "failed to fillup printserver info");
11601 4 : torture_assert(tctx,
11602 : fillup_printserver_info(tctx, p, d2),
11603 : "failed to fillup printserver info");
11604 :
11605 4 : if (!directory_exist(d1->local.driver_directory)) {
11606 4 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11607 : }
11608 :
11609 0 : torture_assert(tctx,
11610 : upload_printer_driver(tctx, dcerpc_server_name(p), d1),
11611 : "failed to upload printer driver");
11612 0 : torture_assert(tctx,
11613 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &d1->info8, add_flags, true, NULL),
11614 : "failed to add driver");
11615 :
11616 0 : torture_assert(tctx,
11617 : upload_printer_driver(tctx, dcerpc_server_name(p), d2),
11618 : "failed to upload printer driver");
11619 0 : torture_assert(tctx,
11620 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &d2->info8, add_flags, true, NULL),
11621 : "failed to add driver");
11622 :
11623 : /* some files are in use by a separate driver, should fail */
11624 0 : torture_assert(tctx,
11625 : test_DeletePrinterDriverEx_exp(tctx, b, server_name_slash,
11626 : d1->info8.driver_name,
11627 : d1->info8.architecture,
11628 : DPD_DELETE_ALL_FILES,
11629 : d1->info8.version,
11630 : WERR_PRINTER_DRIVER_IN_USE),
11631 : "invalid delete driver response");
11632 :
11633 : /* should only delete files not in use by other driver */
11634 0 : torture_assert(tctx,
11635 : test_DeletePrinterDriverEx_exp(tctx, b, server_name_slash,
11636 : d1->info8.driver_name,
11637 : d1->info8.architecture,
11638 : DPD_DELETE_UNUSED_FILES,
11639 : d1->info8.version,
11640 : WERR_OK),
11641 : "failed to delete driver (unused files)");
11642 :
11643 : /* check non-overlapping were deleted */
11644 0 : d1->info8.driver_path = NULL;
11645 0 : d1->info8.help_file = NULL;
11646 0 : torture_assert(tctx,
11647 : check_printer_driver_files(tctx, dcerpc_server_name(p), d1, false),
11648 : "printer driver file check failed");
11649 : /* d2 files should be uneffected */
11650 0 : torture_assert(tctx,
11651 : check_printer_driver_files(tctx, dcerpc_server_name(p), d2, true),
11652 : "printer driver file check failed");
11653 :
11654 0 : torture_assert(tctx,
11655 : test_DeletePrinterDriverEx_exp(tctx, b, server_name_slash,
11656 : d2->info8.driver_name,
11657 : d2->info8.architecture,
11658 : DPD_DELETE_ALL_FILES,
11659 : d2->info8.version,
11660 : WERR_OK),
11661 : "failed to delete driver");
11662 :
11663 0 : torture_assert(tctx,
11664 : check_printer_driver_files(tctx, dcerpc_server_name(p), d2, false),
11665 : "printer driver file check failed");
11666 :
11667 0 : talloc_free(d1);
11668 0 : talloc_free(d2);
11669 0 : return true;
11670 : }
11671 :
11672 2354 : struct torture_suite *torture_rpc_spoolss_driver(TALLOC_CTX *mem_ctx)
11673 : {
11674 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss.driver");
11675 :
11676 2354 : struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
11677 : "driver", &ndr_table_spoolss);
11678 2354 : torture_rpc_tcase_add_test(tcase, "add_driver_64", test_add_driver_64);
11679 2354 : torture_rpc_tcase_add_test(tcase, "add_driver_ex_64", test_add_driver_ex_64);
11680 :
11681 2354 : torture_rpc_tcase_add_test(tcase, "add_driver_32", test_add_driver_32);
11682 2354 : torture_rpc_tcase_add_test(tcase, "add_driver_ex_32", test_add_driver_ex_32);
11683 :
11684 2354 : torture_rpc_tcase_add_test(tcase, "add_driver_adobe", test_add_driver_adobe);
11685 :
11686 2354 : torture_rpc_tcase_add_test(tcase, "add_driver_adobe_cupsaddsmb", test_add_driver_adobe_cupsaddsmb);
11687 :
11688 2354 : torture_rpc_tcase_add_test(tcase, "add_driver_timestamps", test_add_driver_timestamps);
11689 :
11690 2354 : torture_rpc_tcase_add_test(tcase, "multiple_drivers", test_multiple_drivers);
11691 :
11692 2354 : torture_rpc_tcase_add_test(tcase,
11693 : "test_driver_copy_from_directory_64",
11694 : test_driver_copy_from_directory_64);
11695 :
11696 2354 : torture_rpc_tcase_add_test(tcase,
11697 : "test_driver_copy_from_directory_32",
11698 : test_driver_copy_from_directory_32);
11699 :
11700 2354 : torture_rpc_tcase_add_test(tcase, "del_driver_all_files", test_del_driver_all_files);
11701 :
11702 2354 : torture_rpc_tcase_add_test(tcase, "del_driver_unused_files", test_del_driver_unused_files);
11703 :
11704 2354 : return suite;
11705 : }
|