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 0 : 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 0 : switch (level) {
238 0 : case 0:
239 0 : s->info0 = talloc(tctx, struct spoolss_SetPrinterInfo0);
240 0 : break;
241 0 : case 2:
242 0 : s->info2 = talloc(tctx, struct spoolss_SetPrinterInfo2);
243 0 : s->info2->servername = i->info2.servername;
244 0 : s->info2->printername = i->info2.printername;
245 0 : s->info2->sharename = i->info2.sharename;
246 0 : s->info2->portname = i->info2.portname;
247 0 : s->info2->drivername = i->info2.drivername;
248 0 : s->info2->comment = i->info2.comment;
249 0 : s->info2->location = i->info2.location;
250 0 : s->info2->devmode_ptr = 0;
251 0 : s->info2->sepfile = i->info2.sepfile;
252 0 : s->info2->printprocessor = i->info2.printprocessor;
253 0 : s->info2->datatype = i->info2.datatype;
254 0 : s->info2->parameters = i->info2.parameters;
255 0 : s->info2->secdesc_ptr = 0;
256 0 : s->info2->attributes = i->info2.attributes;
257 0 : s->info2->priority = i->info2.priority;
258 0 : s->info2->defaultpriority = i->info2.defaultpriority;
259 0 : s->info2->starttime = i->info2.starttime;
260 0 : s->info2->untiltime = i->info2.untiltime;
261 0 : s->info2->status = i->info2.status;
262 0 : s->info2->cjobs = i->info2.cjobs;
263 0 : s->info2->averageppm = i->info2.averageppm;
264 0 : 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 0 : return true;
277 : }
278 :
279 0 : static bool test_OpenPrinter_server(struct torture_context *tctx,
280 : struct dcerpc_pipe *p,
281 : struct policy_handle *server_handle)
282 : {
283 : NTSTATUS status;
284 : struct spoolss_OpenPrinter op;
285 0 : struct dcerpc_binding_handle *b = p->binding_handle;
286 :
287 0 : op.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
288 0 : op.in.datatype = NULL;
289 0 : op.in.devmode_ctr.devmode= NULL;
290 0 : op.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
291 0 : op.out.handle = server_handle;
292 :
293 0 : torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
294 :
295 0 : status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &op);
296 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed");
297 0 : torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed");
298 :
299 0 : return true;
300 : }
301 :
302 0 : static bool test_EnumPorts(struct torture_context *tctx,
303 : void *private_data)
304 : {
305 0 : struct test_spoolss_context *ctx =
306 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
307 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
308 0 : struct dcerpc_binding_handle *b = p->binding_handle;
309 : NTSTATUS status;
310 : struct spoolss_EnumPorts r;
311 0 : uint16_t levels[] = { 1, 2 };
312 : int i, j;
313 :
314 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
315 0 : int level = levels[i];
316 : DATA_BLOB blob;
317 : uint32_t needed;
318 : uint32_t count;
319 : union spoolss_PortInfo *info;
320 :
321 0 : r.in.servername = "";
322 0 : r.in.level = level;
323 0 : r.in.buffer = NULL;
324 0 : r.in.offered = 0;
325 0 : r.out.needed = &needed;
326 0 : r.out.count = &count;
327 0 : r.out.info = &info;
328 :
329 0 : torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level);
330 :
331 0 : status = dcerpc_spoolss_EnumPorts_r(b, ctx, &r);
332 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
333 0 : if (W_ERROR_IS_OK(r.out.result)) {
334 : /* TODO: do some more checks here */
335 0 : continue;
336 : }
337 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
338 : "EnumPorts unexpected return code");
339 :
340 0 : blob = data_blob_talloc_zero(ctx, needed);
341 0 : r.in.buffer = &blob;
342 0 : r.in.offered = needed;
343 :
344 0 : status = dcerpc_spoolss_EnumPorts_r(b, ctx, &r);
345 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPorts failed");
346 :
347 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
348 :
349 0 : torture_assert(tctx, info, "EnumPorts returned no info");
350 :
351 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, r.in.level, count, needed, 4);
352 :
353 0 : ctx->port_count[level] = count;
354 0 : ctx->ports[level] = info;
355 : }
356 :
357 0 : for (i=1;i<ARRAY_SIZE(levels);i++) {
358 0 : int level = levels[i];
359 0 : int old_level = levels[i-1];
360 0 : 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 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
366 0 : int level = levels[i];
367 0 : for (j=0;j<ctx->port_count[level];j++) {
368 0 : union spoolss_PortInfo *cur = &ctx->ports[level][j];
369 0 : union spoolss_PortInfo *ref = &ctx->ports[2][j];
370 0 : switch (level) {
371 0 : case 1:
372 0 : COMPARE_STRING(tctx, cur->info1, ref->info2, port_name);
373 0 : break;
374 0 : case 2:
375 : /* level 2 is our reference, and it makes no sense to compare it to itself */
376 0 : break;
377 : }
378 : }
379 : }
380 :
381 0 : return true;
382 : }
383 :
384 0 : static bool test_GetPrintProcessorDirectory(struct torture_context *tctx,
385 : void *private_data)
386 : {
387 0 : struct test_spoolss_context *ctx =
388 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
389 :
390 : NTSTATUS status;
391 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
392 0 : struct dcerpc_binding_handle *b = p->binding_handle;
393 : struct spoolss_GetPrintProcessorDirectory r;
394 : struct {
395 : uint16_t level;
396 : const char *server;
397 0 : } levels[] = {{
398 : .level = 1,
399 : .server = NULL
400 : },{
401 : .level = 1,
402 : .server = ""
403 : },{
404 : .level = 78,
405 : .server = ""
406 : },{
407 : .level = 1,
408 0 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
409 : },{
410 : .level = 1024,
411 0 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
412 : }
413 : };
414 : int i;
415 : uint32_t needed;
416 :
417 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
418 0 : int level = levels[i].level;
419 : DATA_BLOB blob;
420 :
421 0 : r.in.server = levels[i].server;
422 0 : r.in.environment = ctx->environment;
423 0 : r.in.level = level;
424 0 : r.in.buffer = NULL;
425 0 : r.in.offered = 0;
426 0 : r.out.needed = &needed;
427 :
428 0 : torture_comment(tctx, "Testing GetPrintProcessorDirectory level %u\n", r.in.level);
429 :
430 0 : status = dcerpc_spoolss_GetPrintProcessorDirectory_r(b, tctx, &r);
431 0 : torture_assert_ntstatus_ok(tctx, status,
432 : "dcerpc_spoolss_GetPrintProcessorDirectory failed");
433 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
434 : "GetPrintProcessorDirectory unexpected return code");
435 :
436 0 : blob = data_blob_talloc_zero(tctx, needed);
437 0 : r.in.buffer = &blob;
438 0 : r.in.offered = needed;
439 :
440 0 : status = dcerpc_spoolss_GetPrintProcessorDirectory_r(b, tctx, &r);
441 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
442 :
443 0 : torture_assert_werr_ok(tctx, r.out.result, "GetPrintProcessorDirectory failed");
444 :
445 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrintProcessorDirectoryInfo, r.out.info, r.in.level, needed, 2);
446 : }
447 :
448 0 : return true;
449 : }
450 :
451 :
452 0 : static bool test_GetPrinterDriverDirectory(struct torture_context *tctx,
453 : void *private_data)
454 : {
455 0 : struct test_spoolss_context *ctx =
456 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
457 :
458 : NTSTATUS status;
459 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
460 0 : struct dcerpc_binding_handle *b = p->binding_handle;
461 : struct spoolss_GetPrinterDriverDirectory r;
462 : struct {
463 : uint16_t level;
464 : const char *server;
465 0 : } levels[] = {{
466 : .level = 1,
467 : .server = NULL
468 : },{
469 : .level = 1,
470 : .server = ""
471 : },{
472 : .level = 78,
473 : .server = ""
474 : },{
475 : .level = 1,
476 0 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
477 : },{
478 : .level = 1024,
479 0 : .server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p))
480 : }
481 : };
482 : int i;
483 : uint32_t needed;
484 :
485 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
486 0 : int level = levels[i].level;
487 : DATA_BLOB blob;
488 :
489 0 : r.in.server = levels[i].server;
490 0 : r.in.environment = ctx->environment;
491 0 : r.in.level = level;
492 0 : r.in.buffer = NULL;
493 0 : r.in.offered = 0;
494 0 : r.out.needed = &needed;
495 :
496 0 : torture_comment(tctx, "Testing GetPrinterDriverDirectory level %u\n", r.in.level);
497 :
498 0 : status = dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r);
499 0 : torture_assert_ntstatus_ok(tctx, status,
500 : "dcerpc_spoolss_GetPrinterDriverDirectory failed");
501 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
502 : "GetPrinterDriverDirectory unexpected return code");
503 :
504 0 : blob = data_blob_talloc_zero(tctx, needed);
505 0 : r.in.buffer = &blob;
506 0 : r.in.offered = needed;
507 :
508 0 : status = dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r);
509 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
510 :
511 0 : torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDriverDirectory failed");
512 :
513 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverDirectoryInfo, r.out.info, r.in.level, needed, 2);
514 : }
515 :
516 0 : return true;
517 : }
518 :
519 0 : 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 : struct spoolss_EnumPrinterDrivers r;
529 : uint32_t needed;
530 : uint32_t count;
531 : union spoolss_DriverInfo *info;
532 : DATA_BLOB buffer;
533 :
534 0 : if (offered > 0) {
535 0 : buffer = data_blob_talloc_zero(tctx, offered);
536 : }
537 :
538 0 : r.in.server = server_name;
539 0 : r.in.environment = environment;
540 0 : r.in.level = level;
541 0 : r.in.buffer = offered ? &buffer : NULL;
542 0 : r.in.offered = offered;
543 0 : r.out.needed = &needed;
544 0 : r.out.count = &count;
545 0 : r.out.info = &info;
546 :
547 0 : torture_comment(tctx, "Testing EnumPrinterDrivers(%s) level %u, offered: %u\n",
548 : r.in.environment, r.in.level, r.in.offered);
549 :
550 0 : torture_assert_ntstatus_ok(tctx,
551 : dcerpc_spoolss_EnumPrinterDrivers_r(b, tctx, &r),
552 : "EnumPrinterDrivers failed");
553 0 : 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 0 : torture_assert_werr_ok(tctx, r.out.result,
564 : "EnumPrinterDrivers failed");
565 :
566 0 : if (count_p) {
567 0 : *count_p = count;
568 : }
569 0 : if (info_p) {
570 0 : *info_p = info;
571 : }
572 :
573 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers, info, r.in.level, count, needed, 4);
574 :
575 0 : return true;
576 :
577 : }
578 :
579 :
580 0 : 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 0 : return test_EnumPrinterDrivers_buffers(tctx, b, server_name,
589 : environment, level, 0,
590 : count_p, info_p);
591 : }
592 :
593 0 : 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 : uint32_t count;
602 : union spoolss_DriverInfo *info;
603 : int i;
604 0 : const char *environment_ret = NULL;
605 :
606 0 : torture_assert(tctx,
607 : test_EnumPrinterDrivers_args(tctx, b, server_name, environment, level, &count, &info),
608 : "failed to enumerate printer drivers");
609 :
610 0 : 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 0 : return false;
658 : }
659 :
660 0 : static bool test_EnumPrinterDrivers(struct torture_context *tctx,
661 : void *private_data)
662 : {
663 0 : struct test_spoolss_context *ctx =
664 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
665 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
666 0 : struct dcerpc_binding_handle *b = p->binding_handle;
667 0 : uint16_t levels[] = { 1, 2, 3, 4, 5, 6, 8 };
668 0 : uint16_t buffer_sizes[] = { 0, 1024, 6040, 0xffff };
669 : 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 0 : const char *server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
675 : const char *environments[2];
676 :
677 0 : environments[0] = SPOOLSS_ARCHITECTURE_ALL;
678 0 : environments[1] = ctx->environment;
679 :
680 0 : for (a=0;a<ARRAY_SIZE(environments);a++) {
681 :
682 0 : for (i=0;i<ARRAY_SIZE(buffer_sizes);i++) {
683 0 : 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 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
692 0 : int level = levels[i];
693 : uint32_t count;
694 : union spoolss_DriverInfo *info;
695 :
696 0 : torture_assert(tctx,
697 : test_EnumPrinterDrivers_args(tctx, b, server_name, environments[a], level, &count, &info),
698 : "failed to enumerate drivers");
699 :
700 0 : ctx->driver_count[level] = count;
701 0 : ctx->drivers[level] = info;
702 : }
703 :
704 0 : for (i=1;i<ARRAY_SIZE(levels);i++) {
705 0 : int level = levels[i];
706 0 : int old_level = levels[i-1];
707 :
708 0 : torture_assert_int_equal(tctx, ctx->driver_count[level], ctx->driver_count[old_level],
709 : "EnumPrinterDrivers invalid value");
710 : }
711 :
712 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
713 0 : int level = levels[i];
714 :
715 0 : 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 0 : return true;
795 : }
796 :
797 0 : static bool test_EnumMonitors(struct torture_context *tctx,
798 : void *private_data)
799 : {
800 0 : struct test_spoolss_context *ctx =
801 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
802 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
803 0 : struct dcerpc_binding_handle *b = p->binding_handle;
804 : NTSTATUS status;
805 : struct spoolss_EnumMonitors r;
806 0 : uint16_t levels[] = { 1, 2 };
807 : int i, j;
808 :
809 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
810 0 : int level = levels[i];
811 : DATA_BLOB blob;
812 : uint32_t needed;
813 : uint32_t count;
814 : union spoolss_MonitorInfo *info;
815 :
816 0 : r.in.servername = "";
817 0 : r.in.level = level;
818 0 : r.in.buffer = NULL;
819 0 : r.in.offered = 0;
820 0 : r.out.needed = &needed;
821 0 : r.out.count = &count;
822 0 : r.out.info = &info;
823 :
824 0 : torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level);
825 :
826 0 : status = dcerpc_spoolss_EnumMonitors_r(b, ctx, &r);
827 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
828 0 : if (W_ERROR_IS_OK(r.out.result)) {
829 : /* TODO: do some more checks here */
830 0 : continue;
831 : }
832 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
833 : "EnumMonitors failed");
834 :
835 0 : blob = data_blob_talloc_zero(ctx, needed);
836 0 : r.in.buffer = &blob;
837 0 : r.in.offered = needed;
838 :
839 0 : status = dcerpc_spoolss_EnumMonitors_r(b, ctx, &r);
840 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumMonitors failed");
841 :
842 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
843 :
844 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumMonitors, info, r.in.level, count, needed, 4);
845 :
846 0 : ctx->monitor_count[level] = count;
847 0 : ctx->monitors[level] = info;
848 : }
849 :
850 0 : for (i=1;i<ARRAY_SIZE(levels);i++) {
851 0 : int level = levels[i];
852 0 : int old_level = levels[i-1];
853 0 : torture_assert_int_equal(tctx, ctx->monitor_count[level], ctx->monitor_count[old_level],
854 : "EnumMonitors invalid value");
855 : }
856 :
857 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
858 0 : int level = levels[i];
859 0 : for (j=0;j<ctx->monitor_count[level];j++) {
860 0 : union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
861 0 : union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
862 0 : switch (level) {
863 0 : case 1:
864 0 : COMPARE_STRING(tctx, cur->info1, ref->info2, monitor_name);
865 0 : break;
866 0 : case 2:
867 0 : 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 0 : break;
870 : }
871 : }
872 : }
873 :
874 0 : return true;
875 : }
876 :
877 0 : 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 : struct spoolss_EnumPrintProcessors r;
886 : DATA_BLOB blob;
887 : uint32_t needed;
888 : uint32_t count;
889 : union spoolss_PrintProcessorInfo *info;
890 :
891 0 : r.in.servername = "";
892 0 : r.in.environment = environment;
893 0 : r.in.level = level;
894 0 : r.in.buffer = NULL;
895 0 : r.in.offered = 0;
896 0 : r.out.needed = &needed;
897 0 : r.out.count = &count;
898 0 : r.out.info = &info;
899 :
900 0 : torture_comment(tctx, "Testing EnumPrintProcessors(%s) level %u\n",
901 : r.in.environment, r.in.level);
902 :
903 0 : torture_assert_ntstatus_ok(tctx,
904 : dcerpc_spoolss_EnumPrintProcessors_r(b, tctx, &r),
905 : "EnumPrintProcessors failed");
906 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
907 0 : blob = data_blob_talloc_zero(tctx, needed);
908 0 : r.in.buffer = &blob;
909 0 : r.in.offered = needed;
910 0 : torture_assert_ntstatus_ok(tctx,
911 : dcerpc_spoolss_EnumPrintProcessors_r(b, tctx, &r),
912 : "EnumPrintProcessors failed");
913 : }
914 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
915 : "EnumPrintProcessors failed");
916 :
917 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessors, info, level, count, needed, 4);
918 :
919 0 : if (count_p) {
920 0 : *count_p = count;
921 : }
922 0 : if (info_p) {
923 0 : *info_p = info;
924 : }
925 :
926 0 : return true;
927 : }
928 :
929 0 : static bool test_EnumPrintProcessors(struct torture_context *tctx,
930 : void *private_data)
931 : {
932 0 : struct test_spoolss_context *ctx =
933 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
934 :
935 0 : uint16_t levels[] = {0, 1, 2, 3, 32, 256 };
936 0 : uint16_t ok[] = {0, 1, 0, 0, 0, 0 };
937 : int i;
938 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
939 0 : struct dcerpc_binding_handle *b = p->binding_handle;
940 :
941 0 : torture_assert(tctx,
942 : test_EnumPrintProcessors_level(tctx, b, "phantasy", 1, NULL, NULL, WERR_INVALID_ENVIRONMENT),
943 : "test_EnumPrintProcessors_level failed");
944 :
945 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
946 : union spoolss_PrintProcessorInfo *info;
947 : uint32_t count;
948 0 : WERROR expected_result = ok[i] ? WERR_OK : WERR_INVALID_LEVEL;
949 :
950 0 : 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 0 : return true;
956 : }
957 :
958 0 : 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 : struct spoolss_EnumPrintProcessorDataTypes r;
967 : DATA_BLOB blob;
968 : uint32_t needed;
969 : uint32_t count;
970 : union spoolss_PrintProcDataTypesInfo *info;
971 :
972 0 : r.in.servername = "";
973 0 : r.in.print_processor_name = print_processor_name;
974 0 : r.in.level = level;
975 0 : r.in.buffer = NULL;
976 0 : r.in.offered = 0;
977 0 : r.out.needed = &needed;
978 0 : r.out.count = &count;
979 0 : r.out.info = &info;
980 :
981 0 : torture_comment(tctx, "Testing EnumPrintProcessorDataTypes(%s) level %u\n",
982 : r.in.print_processor_name, r.in.level);
983 :
984 0 : torture_assert_ntstatus_ok(tctx,
985 : dcerpc_spoolss_EnumPrintProcessorDataTypes_r(b, tctx, &r),
986 : "EnumPrintProcessorDataTypes failed");
987 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
988 0 : blob = data_blob_talloc_zero(tctx, needed);
989 0 : r.in.buffer = &blob;
990 0 : r.in.offered = needed;
991 0 : torture_assert_ntstatus_ok(tctx,
992 : dcerpc_spoolss_EnumPrintProcessorDataTypes_r(b, tctx, &r),
993 : "EnumPrintProcessorDataTypes failed");
994 : }
995 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
996 : "EnumPrintProcessorDataTypes failed");
997 :
998 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessorDataTypes, info, level, count, needed, 4);
999 :
1000 0 : if (count_p) {
1001 0 : *count_p = count;
1002 : }
1003 0 : if (info_p) {
1004 0 : *info_p = info;
1005 : }
1006 :
1007 0 : return true;
1008 : }
1009 :
1010 0 : static bool test_EnumPrintProcessorDataTypes(struct torture_context *tctx,
1011 : void *private_data)
1012 : {
1013 0 : struct test_spoolss_context *ctx =
1014 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
1015 :
1016 0 : uint16_t levels[] = {0, 1, 2, 3, 32, 256 };
1017 0 : uint16_t ok[] = {0, 1, 0, 0, 0, 0 };
1018 : int i;
1019 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
1020 0 : struct dcerpc_binding_handle *b = p->binding_handle;
1021 :
1022 0 : torture_assert(tctx,
1023 : test_EnumPrintProcessorDataTypes_level(tctx, b, NULL, 1, NULL, NULL, WERR_UNKNOWN_PRINTPROCESSOR),
1024 : "test_EnumPrintProcessorDataTypes_level failed");
1025 :
1026 0 : torture_assert(tctx,
1027 : test_EnumPrintProcessorDataTypes_level(tctx, b, "nonexisting", 1, NULL, NULL, WERR_UNKNOWN_PRINTPROCESSOR),
1028 : "test_EnumPrintProcessorDataTypes_level failed");
1029 :
1030 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1031 0 : int level = levels[i];
1032 : uint32_t count;
1033 : union spoolss_PrintProcDataTypesInfo *info;
1034 0 : WERROR expected_result = ok[i] ? WERR_OK : WERR_INVALID_LEVEL;
1035 :
1036 0 : torture_assert(tctx,
1037 : test_EnumPrintProcessorDataTypes_level(tctx, b, "winprint", level, &count, &info, expected_result),
1038 : "test_EnumPrintProcessorDataTypes_level failed");
1039 : }
1040 :
1041 : {
1042 : union spoolss_PrintProcessorInfo *info;
1043 : uint32_t count;
1044 :
1045 0 : torture_assert(tctx,
1046 : test_EnumPrintProcessors_level(tctx, b, ctx->environment, 1, &count, &info, WERR_OK),
1047 : "test_EnumPrintProcessors_level failed");
1048 :
1049 0 : for (i=0; i < count; i++) {
1050 0 : 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 0 : return true;
1058 : }
1059 :
1060 0 : static bool test_EnumPrinters(struct torture_context *tctx,
1061 : void *private_data)
1062 : {
1063 0 : struct test_spoolss_context *ctx =
1064 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
1065 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
1066 0 : struct dcerpc_binding_handle *b = p->binding_handle;
1067 : struct spoolss_EnumPrinters r;
1068 : NTSTATUS status;
1069 0 : uint16_t levels[] = { 0, 1, 2, 4, 5 };
1070 : int i, j;
1071 :
1072 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1073 0 : int level = levels[i];
1074 : DATA_BLOB blob;
1075 : uint32_t needed;
1076 : uint32_t count;
1077 : union spoolss_PrinterInfo *info;
1078 :
1079 0 : r.in.flags = PRINTER_ENUM_LOCAL;
1080 0 : r.in.server = "";
1081 0 : r.in.level = level;
1082 0 : r.in.buffer = NULL;
1083 0 : r.in.offered = 0;
1084 0 : r.out.needed = &needed;
1085 0 : r.out.count = &count;
1086 0 : r.out.info = &info;
1087 :
1088 0 : torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
1089 :
1090 0 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &r);
1091 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
1092 0 : if (W_ERROR_IS_OK(r.out.result)) {
1093 : /* TODO: do some more checks here */
1094 0 : continue;
1095 : }
1096 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
1097 : "EnumPrinters unexpected return code");
1098 :
1099 0 : blob = data_blob_talloc_zero(ctx, needed);
1100 0 : r.in.buffer = &blob;
1101 0 : r.in.offered = needed;
1102 :
1103 0 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &r);
1104 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrinters failed");
1105 :
1106 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
1107 :
1108 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
1109 :
1110 0 : ctx->printer_count[level] = count;
1111 0 : ctx->printers[level] = info;
1112 : }
1113 :
1114 0 : for (i=1;i<ARRAY_SIZE(levels);i++) {
1115 0 : int level = levels[i];
1116 0 : int old_level = levels[i-1];
1117 0 : torture_assert_int_equal(tctx, ctx->printer_count[level], ctx->printer_count[old_level],
1118 : "EnumPrinters invalid value");
1119 : }
1120 :
1121 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1122 0 : int level = levels[i];
1123 0 : for (j=0;j<ctx->printer_count[level];j++) {
1124 0 : union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
1125 0 : union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
1126 0 : switch (level) {
1127 0 : case 0:
1128 0 : COMPARE_STRING(tctx, cur->info0, ref->info2, printername);
1129 0 : COMPARE_STRING(tctx, cur->info0, ref->info2, servername);
1130 0 : 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 0 : 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 0 : break;
1158 0 : 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 0 : COMPARE_STRING(tctx, cur->info1, ref->info2, comment);
1163 0 : break;
1164 0 : case 2:
1165 : /* level 2 is our reference, and it makes no sense to compare it to itself */
1166 0 : break;
1167 0 : case 4:
1168 0 : COMPARE_STRING(tctx, cur->info4, ref->info2, printername);
1169 0 : COMPARE_STRING(tctx, cur->info4, ref->info2, servername);
1170 0 : COMPARE_UINT32(tctx, cur->info4, ref->info2, attributes);
1171 0 : break;
1172 0 : case 5:
1173 0 : COMPARE_STRING(tctx, cur->info5, ref->info2, printername);
1174 0 : COMPARE_STRING(tctx, cur->info5, ref->info2, portname);
1175 0 : 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 0 : 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 0 : 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 0 : 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 : struct spoolss_GetPrinter r;
1204 : uint32_t needed;
1205 :
1206 0 : r.in.handle = handle;
1207 0 : r.in.level = level;
1208 0 : r.in.buffer = NULL;
1209 0 : r.in.offered = 0;
1210 0 : r.out.needed = &needed;
1211 :
1212 0 : torture_comment(tctx, "Testing GetPrinter level %u\n", r.in.level);
1213 :
1214 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
1215 : "GetPrinter failed");
1216 :
1217 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1218 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
1219 0 : r.in.buffer = &blob;
1220 0 : r.in.offered = needed;
1221 :
1222 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinter_r(b, tctx, &r),
1223 : "GetPrinter failed");
1224 : }
1225 :
1226 0 : torture_assert_werr_equal(tctx,
1227 : r.out.result, expected_werror,
1228 : "GetPrinter failed");
1229 :
1230 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo, r.out.info, r.in.level, needed, 4);
1231 :
1232 0 : if (info && r.out.info) {
1233 0 : *info = *r.out.info;
1234 : }
1235 :
1236 0 : return true;
1237 : }
1238 :
1239 0 : 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 0 : return test_GetPrinter_level_exp(tctx, b, handle, level, WERR_OK, info);
1246 : }
1247 :
1248 0 : 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 0 : uint32_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1254 : int i;
1255 :
1256 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
1257 :
1258 : union spoolss_PrinterInfo info;
1259 :
1260 0 : ZERO_STRUCT(info);
1261 :
1262 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, levels[i], &info),
1263 : "failed to call GetPrinter");
1264 :
1265 0 : 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 0 : return true;
1273 : }
1274 :
1275 0 : 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 : struct spoolss_SetPrinter r;
1284 :
1285 0 : r.in.handle = handle;
1286 0 : r.in.info_ctr = info_ctr;
1287 0 : r.in.devmode_ctr = devmode_ctr;
1288 0 : r.in.secdesc_ctr = secdesc_ctr;
1289 0 : r.in.command = command;
1290 :
1291 0 : torture_comment(tctx, "Testing SetPrinter level %d\n", r.in.info_ctr->level);
1292 :
1293 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter_r(b, tctx, &r),
1294 : "failed to call SetPrinter");
1295 0 : 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 0 : 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 : struct spoolss_SetPrinter r;
1307 0 : uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1308 : int i;
1309 :
1310 : struct spoolss_SetPrinterInfoCtr info_ctr;
1311 : struct spoolss_DevmodeContainer devmode_ctr;
1312 : 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 : struct spoolss_SetPrinterInfo0 info0;
1337 : struct spoolss_SetPrinterInfo1 info1;
1338 : struct spoolss_SetPrinterInfo2 info2;
1339 : struct spoolss_SetPrinterInfo3 info3;
1340 : struct spoolss_SetPrinterInfo4 info4;
1341 : struct spoolss_SetPrinterInfo5 info5;
1342 : struct spoolss_SetPrinterInfo6 info6;
1343 : struct spoolss_SetPrinterInfo7 info7;
1344 : struct spoolss_SetPrinterInfo8 info8;
1345 : 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 : 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 0 : static void clear_info2(struct spoolss_SetPrinterInfoCtr *r)
1466 : {
1467 0 : 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 0 : }
1472 :
1473 0 : static bool test_PrinterInfo(struct torture_context *tctx,
1474 : struct dcerpc_binding_handle *b,
1475 : struct policy_handle *handle)
1476 : {
1477 : NTSTATUS status;
1478 : struct spoolss_SetPrinter s;
1479 : struct spoolss_GetPrinter q;
1480 : struct spoolss_GetPrinter q0;
1481 : struct spoolss_SetPrinterInfoCtr info_ctr;
1482 : union spoolss_PrinterInfo info;
1483 : struct spoolss_DevmodeContainer devmode_ctr;
1484 : struct sec_desc_buf secdesc_ctr;
1485 : uint32_t needed;
1486 0 : bool ret = true;
1487 : int i;
1488 :
1489 0 : uint32_t status_list[] = {
1490 : /* these do not stick
1491 : PRINTER_STATUS_PAUSED,
1492 : PRINTER_STATUS_ERROR,
1493 : PRINTER_STATUS_PENDING_DELETION, */
1494 : PRINTER_STATUS_PAPER_JAM,
1495 : PRINTER_STATUS_PAPER_OUT,
1496 : PRINTER_STATUS_MANUAL_FEED,
1497 : PRINTER_STATUS_PAPER_PROBLEM,
1498 : PRINTER_STATUS_OFFLINE,
1499 : PRINTER_STATUS_IO_ACTIVE,
1500 : PRINTER_STATUS_BUSY,
1501 : PRINTER_STATUS_PRINTING,
1502 : PRINTER_STATUS_OUTPUT_BIN_FULL,
1503 : PRINTER_STATUS_NOT_AVAILABLE,
1504 : PRINTER_STATUS_WAITING,
1505 : PRINTER_STATUS_PROCESSING,
1506 : PRINTER_STATUS_INITIALIZING,
1507 : PRINTER_STATUS_WARMING_UP,
1508 : PRINTER_STATUS_TONER_LOW,
1509 : PRINTER_STATUS_NO_TONER,
1510 : PRINTER_STATUS_PAGE_PUNT,
1511 : PRINTER_STATUS_USER_INTERVENTION,
1512 : PRINTER_STATUS_OUT_OF_MEMORY,
1513 : PRINTER_STATUS_DOOR_OPEN,
1514 : PRINTER_STATUS_SERVER_UNKNOWN,
1515 : PRINTER_STATUS_POWER_SAVE,
1516 : /* these do not stick
1517 : 0x02000000,
1518 : 0x04000000,
1519 : 0x08000000,
1520 : 0x10000000,
1521 : 0x20000000,
1522 : 0x40000000,
1523 : 0x80000000 */
1524 : };
1525 0 : uint32_t default_attribute = PRINTER_ATTRIBUTE_LOCAL;
1526 0 : uint32_t attribute_list[] = {
1527 : PRINTER_ATTRIBUTE_QUEUED,
1528 : /* fails with WERR_INVALID_DATATYPE:
1529 : PRINTER_ATTRIBUTE_DIRECT, */
1530 : /* does not stick
1531 : PRINTER_ATTRIBUTE_DEFAULT, */
1532 : PRINTER_ATTRIBUTE_SHARED,
1533 : /* does not stick
1534 : PRINTER_ATTRIBUTE_NETWORK, */
1535 : PRINTER_ATTRIBUTE_HIDDEN,
1536 : PRINTER_ATTRIBUTE_LOCAL,
1537 : PRINTER_ATTRIBUTE_ENABLE_DEVQ,
1538 : PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS,
1539 : PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST,
1540 : PRINTER_ATTRIBUTE_WORK_OFFLINE,
1541 : /* does not stick
1542 : PRINTER_ATTRIBUTE_ENABLE_BIDI, */
1543 : /* fails with WERR_INVALID_DATATYPE:
1544 : PRINTER_ATTRIBUTE_RAW_ONLY, */
1545 : /* these do not stick
1546 : PRINTER_ATTRIBUTE_PUBLISHED,
1547 : PRINTER_ATTRIBUTE_FAX,
1548 : PRINTER_ATTRIBUTE_TS,
1549 : 0x00010000,
1550 : 0x00020000,
1551 : 0x00040000,
1552 : 0x00080000,
1553 : 0x00100000,
1554 : 0x00200000,
1555 : 0x00400000,
1556 : 0x00800000,
1557 : 0x01000000,
1558 : 0x02000000,
1559 : 0x04000000,
1560 : 0x08000000,
1561 : 0x10000000,
1562 : 0x20000000,
1563 : 0x40000000,
1564 : 0x80000000 */
1565 : };
1566 :
1567 0 : torture_skip(tctx, "Printer Info test is currently broken, skipping");
1568 :
1569 :
1570 : ZERO_STRUCT(devmode_ctr);
1571 : ZERO_STRUCT(secdesc_ctr);
1572 :
1573 : s.in.handle = handle;
1574 : s.in.command = 0;
1575 : s.in.info_ctr = &info_ctr;
1576 : s.in.devmode_ctr = &devmode_ctr;
1577 : s.in.secdesc_ctr = &secdesc_ctr;
1578 :
1579 : q.in.handle = handle;
1580 : q.out.info = &info;
1581 : q0 = q;
1582 :
1583 : #define TESTGETCALL(call, r) \
1584 : r.in.buffer = NULL; \
1585 : r.in.offered = 0;\
1586 : r.out.needed = &needed; \
1587 : status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1588 : if (!NT_STATUS_IS_OK(status)) { \
1589 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1590 : r.in.level, nt_errstr(status), __location__); \
1591 : ret = false; \
1592 : break; \
1593 : }\
1594 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\
1595 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed); \
1596 : r.in.buffer = &blob; \
1597 : r.in.offered = needed; \
1598 : }\
1599 : status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1600 : if (!NT_STATUS_IS_OK(status)) { \
1601 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1602 : r.in.level, nt_errstr(status), __location__); \
1603 : ret = false; \
1604 : break; \
1605 : } \
1606 : if (!W_ERROR_IS_OK(r.out.result)) { \
1607 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1608 : r.in.level, win_errstr(r.out.result), __location__); \
1609 : ret = false; \
1610 : break; \
1611 : }
1612 :
1613 :
1614 : #define TESTSETCALL_EXP(call, r, err) \
1615 : clear_info2(&info_ctr);\
1616 : status = dcerpc_spoolss_ ##call## _r(b, tctx, &r); \
1617 : if (!NT_STATUS_IS_OK(status)) { \
1618 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1619 : r.in.info_ctr->level, nt_errstr(status), __location__); \
1620 : ret = false; \
1621 : break; \
1622 : } \
1623 : if (!W_ERROR_IS_OK(err)) { \
1624 : if (!W_ERROR_EQUAL(err, r.out.result)) { \
1625 : torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \
1626 : r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \
1627 : ret = false; \
1628 : } \
1629 : break; \
1630 : } \
1631 : if (!W_ERROR_IS_OK(r.out.result)) { \
1632 : torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1633 : r.in.info_ctr->level, win_errstr(r.out.result), __location__); \
1634 : ret = false; \
1635 : break; \
1636 : }
1637 :
1638 : #define TESTSETCALL(call, r) \
1639 : TESTSETCALL_EXP(call, r, WERR_OK)
1640 :
1641 : #define STRING_EQUAL(s1, s2, field) \
1642 : if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
1643 : torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1644 : #field, s2, __location__); \
1645 : ret = false; \
1646 : break; \
1647 : }
1648 :
1649 : #define MEM_EQUAL(s1, s2, length, field) \
1650 : if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
1651 : torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1652 : #field, (const char *)s2, __location__); \
1653 : ret = false; \
1654 : break; \
1655 : }
1656 :
1657 : #define INT_EQUAL(i1, i2, field) \
1658 : if (i1 != i2) { \
1659 : torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
1660 : #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
1661 : ret = false; \
1662 : break; \
1663 : }
1664 :
1665 : #define SD_EQUAL(sd1, sd2, field) \
1666 : if (!security_descriptor_equal(sd1, sd2)) { \
1667 : torture_comment(tctx, "Failed to set %s (%s)\n", \
1668 : #field, __location__); \
1669 : ret = false; \
1670 : break; \
1671 : }
1672 :
1673 : #define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \
1674 : void *p; \
1675 : torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1676 : q.in.level = lvl1; \
1677 : TESTGETCALL(GetPrinter, q) \
1678 : info_ctr.level = lvl1; \
1679 : p = (void *)&q.out.info->info ## lvl1; \
1680 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
1681 : info_ctr.info.info ## lvl1->field1 = value;\
1682 : TESTSETCALL_EXP(SetPrinter, s, err) \
1683 : info_ctr.info.info ## lvl1->field1 = ""; \
1684 : TESTGETCALL(GetPrinter, q) \
1685 : info_ctr.info.info ## lvl1->field1 = value; \
1686 : STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \
1687 : q.in.level = lvl2; \
1688 : TESTGETCALL(GetPrinter, q) \
1689 : p = (void *)&q.out.info->info ## lvl2; \
1690 : info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)p; \
1691 : STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \
1692 : } while (0)
1693 :
1694 : #define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \
1695 : TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, WERR_OK); \
1696 : } while (0);
1697 :
1698 : #define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
1699 : void *p; \
1700 : torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1701 : q.in.level = lvl1; \
1702 : TESTGETCALL(GetPrinter, q) \
1703 : info_ctr.level = lvl1; \
1704 : p = (void *)&q.out.info->info ## lvl1; \
1705 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
1706 : info_ctr.info.info ## lvl1->field1 = value; \
1707 : TESTSETCALL(SetPrinter, s) \
1708 : info_ctr.info.info ## lvl1->field1 = 0; \
1709 : TESTGETCALL(GetPrinter, q) \
1710 : p = (void *)&q.out.info->info ## lvl1; \
1711 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
1712 : INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \
1713 : q.in.level = lvl2; \
1714 : TESTGETCALL(GetPrinter, q) \
1715 : p = (void *)&q.out.info->info ## lvl2; \
1716 : info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)p; \
1717 : INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \
1718 : } while (0)
1719 :
1720 : #define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
1721 : TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value); \
1722 : } while (0)
1723 :
1724 : q0.in.level = 0;
1725 : do { TESTGETCALL(GetPrinter, q0) } while (0);
1726 :
1727 : TEST_PRINTERINFO_STRING(2, comment, 1, comment, "xx2-1 comment");
1728 : TEST_PRINTERINFO_STRING(2, comment, 2, comment, "xx2-2 comment");
1729 :
1730 : /* level 0 printername does not stick */
1731 : /* TEST_PRINTERINFO_STRING(2, printername, 0, printername, "xx2-0 printer"); */
1732 : TEST_PRINTERINFO_STRING(2, printername, 1, name, "xx2-1 printer");
1733 : TEST_PRINTERINFO_STRING(2, printername, 2, printername, "xx2-2 printer");
1734 : TEST_PRINTERINFO_STRING(2, printername, 4, printername, "xx2-4 printer");
1735 : TEST_PRINTERINFO_STRING(2, printername, 5, printername, "xx2-5 printer");
1736 : /* TEST_PRINTERINFO_STRING(4, printername, 0, printername, "xx4-0 printer"); */
1737 : TEST_PRINTERINFO_STRING(4, printername, 1, name, "xx4-1 printer");
1738 : TEST_PRINTERINFO_STRING(4, printername, 2, printername, "xx4-2 printer");
1739 : TEST_PRINTERINFO_STRING(4, printername, 4, printername, "xx4-4 printer");
1740 : TEST_PRINTERINFO_STRING(4, printername, 5, printername, "xx4-5 printer");
1741 : /* TEST_PRINTERINFO_STRING(5, printername, 0, printername, "xx5-0 printer"); */
1742 : TEST_PRINTERINFO_STRING(5, printername, 1, name, "xx5-1 printer");
1743 : TEST_PRINTERINFO_STRING(5, printername, 2, printername, "xx5-2 printer");
1744 : TEST_PRINTERINFO_STRING(5, printername, 4, printername, "xx5-4 printer");
1745 : TEST_PRINTERINFO_STRING(5, printername, 5, printername, "xx5-5 printer");
1746 :
1747 : /* servername can be set but does not stick
1748 : TEST_PRINTERINFO_STRING(2, servername, 0, servername, "xx2-0 servername");
1749 : TEST_PRINTERINFO_STRING(2, servername, 2, servername, "xx2-2 servername");
1750 : TEST_PRINTERINFO_STRING(2, servername, 4, servername, "xx2-4 servername");
1751 : */
1752 :
1753 : /* passing an invalid port will result in WERR_UNKNOWN_PORT */
1754 : TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 2, portname, "xx2-2 portname", WERR_UNKNOWN_PORT);
1755 : TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 5, portname, "xx2-5 portname", WERR_UNKNOWN_PORT);
1756 : TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 2, portname, "xx5-2 portname", WERR_UNKNOWN_PORT);
1757 : TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 5, portname, "xx5-5 portname", WERR_UNKNOWN_PORT);
1758 :
1759 : TEST_PRINTERINFO_STRING(2, sharename, 2, sharename, "xx2-2 sharename");
1760 : /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
1761 : TEST_PRINTERINFO_STRING_EXP_ERR(2, drivername, 2, drivername, "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER);
1762 : TEST_PRINTERINFO_STRING(2, location, 2, location, "xx2-2 location");
1763 : /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
1764 : TEST_PRINTERINFO_STRING_EXP_ERR(2, sepfile, 2, sepfile, "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE);
1765 : /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
1766 : TEST_PRINTERINFO_STRING_EXP_ERR(2, printprocessor, 2, printprocessor, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR);
1767 : TEST_PRINTERINFO_STRING(2, datatype, 2, datatype, "xx2-2 datatype");
1768 : TEST_PRINTERINFO_STRING(2, parameters, 2, parameters, "xx2-2 parameters");
1769 :
1770 : for (i=0; i < ARRAY_SIZE(attribute_list); i++) {
1771 : /* TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags,
1772 : attribute_list[i],
1773 : (attribute_list[i] | default_attribute)
1774 : ); */
1775 : TEST_PRINTERINFO_INT_EXP(2, attributes, 2, attributes,
1776 : attribute_list[i],
1777 : (attribute_list[i] | default_attribute)
1778 : );
1779 : TEST_PRINTERINFO_INT_EXP(2, attributes, 4, attributes,
1780 : attribute_list[i],
1781 : (attribute_list[i] | default_attribute)
1782 : );
1783 : TEST_PRINTERINFO_INT_EXP(2, attributes, 5, attributes,
1784 : attribute_list[i],
1785 : (attribute_list[i] | default_attribute)
1786 : );
1787 : /* TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags,
1788 : attribute_list[i],
1789 : (attribute_list[i] | default_attribute)
1790 : ); */
1791 : TEST_PRINTERINFO_INT_EXP(4, attributes, 2, attributes,
1792 : attribute_list[i],
1793 : (attribute_list[i] | default_attribute)
1794 : );
1795 : TEST_PRINTERINFO_INT_EXP(4, attributes, 4, attributes,
1796 : attribute_list[i],
1797 : (attribute_list[i] | default_attribute)
1798 : );
1799 : TEST_PRINTERINFO_INT_EXP(4, attributes, 5, attributes,
1800 : attribute_list[i],
1801 : (attribute_list[i] | default_attribute)
1802 : );
1803 : /* TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags,
1804 : attribute_list[i],
1805 : (attribute_list[i] | default_attribute)
1806 : ); */
1807 : TEST_PRINTERINFO_INT_EXP(5, attributes, 2, attributes,
1808 : attribute_list[i],
1809 : (attribute_list[i] | default_attribute)
1810 : );
1811 : TEST_PRINTERINFO_INT_EXP(5, attributes, 4, attributes,
1812 : attribute_list[i],
1813 : (attribute_list[i] | default_attribute)
1814 : );
1815 : TEST_PRINTERINFO_INT_EXP(5, attributes, 5, attributes,
1816 : attribute_list[i],
1817 : (attribute_list[i] | default_attribute)
1818 : );
1819 : }
1820 :
1821 : for (i=0; i < ARRAY_SIZE(status_list); i++) {
1822 : /* level 2 sets do not stick
1823 : TEST_PRINTERINFO_INT(2, status, 0, status, status_list[i]);
1824 : TEST_PRINTERINFO_INT(2, status, 2, status, status_list[i]);
1825 : TEST_PRINTERINFO_INT(2, status, 6, status, status_list[i]); */
1826 : TEST_PRINTERINFO_INT(6, status, 0, status, status_list[i]);
1827 : TEST_PRINTERINFO_INT(6, status, 2, status, status_list[i]);
1828 : TEST_PRINTERINFO_INT(6, status, 6, status, status_list[i]);
1829 : }
1830 :
1831 : /* priorities need to be between 0 and 99
1832 : passing an invalid priority will result in WERR_INVALID_PRIORITY */
1833 : TEST_PRINTERINFO_INT(2, priority, 2, priority, 0);
1834 : TEST_PRINTERINFO_INT(2, priority, 2, priority, 1);
1835 : TEST_PRINTERINFO_INT(2, priority, 2, priority, 99);
1836 : /* TEST_PRINTERINFO_INT(2, priority, 2, priority, 100); */
1837 : TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 0);
1838 : TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 1);
1839 : TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 99);
1840 : /* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */
1841 :
1842 : TEST_PRINTERINFO_INT(2, starttime, 2, starttime, __LINE__);
1843 : TEST_PRINTERINFO_INT(2, untiltime, 2, untiltime, __LINE__);
1844 :
1845 : /* does not stick
1846 : TEST_PRINTERINFO_INT(2, cjobs, 2, cjobs, __LINE__);
1847 : TEST_PRINTERINFO_INT(2, averageppm, 2, averageppm, __LINE__); */
1848 :
1849 : /* does not stick
1850 : TEST_PRINTERINFO_INT(5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__);
1851 : TEST_PRINTERINFO_INT(5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */
1852 :
1853 : /* FIXME: gd also test devmode and secdesc behavior */
1854 :
1855 : {
1856 : /* verify composition of level 1 description field */
1857 : const char *description;
1858 : const char *tmp;
1859 :
1860 : q0.in.level = 1;
1861 : do { TESTGETCALL(GetPrinter, q0) } while (0);
1862 :
1863 : description = talloc_strdup(tctx, q0.out.info->info1.description);
1864 :
1865 : q0.in.level = 2;
1866 : do { TESTGETCALL(GetPrinter, q0) } while (0);
1867 :
1868 : tmp = talloc_asprintf(tctx, "%s,%s,%s",
1869 : q0.out.info->info2.printername,
1870 : q0.out.info->info2.drivername,
1871 : q0.out.info->info2.location);
1872 :
1873 : do { STRING_EQUAL(description, tmp, "description")} while (0);
1874 : }
1875 :
1876 : return ret;
1877 : }
1878 :
1879 0 : static bool test_security_descriptor_equal(struct torture_context *tctx,
1880 : const struct security_descriptor *sd1,
1881 : const struct security_descriptor *sd2)
1882 : {
1883 0 : if (sd1 == sd2) {
1884 0 : return true;
1885 : }
1886 :
1887 0 : if (!sd1 || !sd2) {
1888 0 : torture_comment(tctx, "%s\n", __location__);
1889 0 : return false;
1890 : }
1891 :
1892 0 : torture_assert_int_equal(tctx, sd1->revision, sd2->revision, "revision mismatch");
1893 0 : torture_assert_int_equal(tctx, sd1->type, sd2->type, "type mismatch");
1894 :
1895 0 : torture_assert_sid_equal(tctx, sd1->owner_sid, sd2->owner_sid, "owner mismatch");
1896 0 : torture_assert_sid_equal(tctx, sd1->group_sid, sd2->group_sid, "group mismatch");
1897 :
1898 0 : if (!security_acl_equal(sd1->sacl, sd2->sacl)) {
1899 0 : torture_comment(tctx, "%s: sacl mismatch\n", __location__);
1900 0 : NDR_PRINT_DEBUG(security_acl, sd1->sacl);
1901 0 : NDR_PRINT_DEBUG(security_acl, sd2->sacl);
1902 0 : return false;
1903 : }
1904 0 : if (!security_acl_equal(sd1->dacl, sd2->dacl)) {
1905 0 : torture_comment(tctx, "%s: dacl mismatch\n", __location__);
1906 0 : NDR_PRINT_DEBUG(security_acl, sd1->dacl);
1907 0 : NDR_PRINT_DEBUG(security_acl, sd2->dacl);
1908 0 : return false;
1909 : }
1910 :
1911 0 : return true;
1912 : }
1913 :
1914 0 : static bool test_sd_set_level(struct torture_context *tctx,
1915 : struct dcerpc_binding_handle *b,
1916 : struct policy_handle *handle,
1917 : uint32_t level,
1918 : struct security_descriptor *sd)
1919 : {
1920 : struct spoolss_SetPrinterInfoCtr info_ctr;
1921 : struct spoolss_DevmodeContainer devmode_ctr;
1922 : struct sec_desc_buf secdesc_ctr;
1923 : union spoolss_SetPrinterInfo sinfo;
1924 : union spoolss_PrinterInfo info;
1925 : struct spoolss_SetPrinterInfo3 info3;
1926 :
1927 0 : ZERO_STRUCT(devmode_ctr);
1928 0 : ZERO_STRUCT(secdesc_ctr);
1929 :
1930 0 : switch (level) {
1931 0 : case 2: {
1932 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1933 0 : torture_assert(tctx, PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
1934 :
1935 0 : info_ctr.level = 2;
1936 0 : info_ctr.info = sinfo;
1937 :
1938 0 : break;
1939 : }
1940 0 : case 3: {
1941 :
1942 0 : info3.sec_desc_ptr = 0;
1943 :
1944 0 : info_ctr.level = 3;
1945 0 : info_ctr.info.info3 = &info3;
1946 :
1947 0 : break;
1948 : }
1949 0 : default:
1950 0 : return false;
1951 : }
1952 :
1953 0 : secdesc_ctr.sd = sd;
1954 :
1955 0 : torture_assert(tctx,
1956 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0), "");
1957 :
1958 0 : return true;
1959 : }
1960 :
1961 0 : static bool test_PrinterInfo_SDs(struct torture_context *tctx,
1962 : struct dcerpc_binding_handle *b,
1963 : struct policy_handle *handle)
1964 : {
1965 : union spoolss_PrinterInfo info;
1966 : struct security_descriptor *sd1, *sd2;
1967 : int i;
1968 :
1969 : /* just compare level 2 and level 3 */
1970 :
1971 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1972 :
1973 0 : sd1 = info.info2.secdesc;
1974 :
1975 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 3, &info), "");
1976 :
1977 0 : sd2 = info.info3.secdesc;
1978 :
1979 0 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
1980 : "SD level 2 != SD level 3");
1981 :
1982 :
1983 : /* query level 2, set level 2, query level 2 */
1984 :
1985 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1986 :
1987 0 : sd1 = info.info2.secdesc;
1988 :
1989 0 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 2, sd1), "");
1990 :
1991 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
1992 :
1993 0 : sd2 = info.info2.secdesc;
1994 0 : if (sd1->type & SEC_DESC_DACL_DEFAULTED) {
1995 0 : torture_comment(tctx, "removing SEC_DESC_DACL_DEFAULTED\n");
1996 0 : sd1->type &= ~SEC_DESC_DACL_DEFAULTED;
1997 : }
1998 :
1999 0 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
2000 : "SD level 2 != SD level 2 after SD has been set via level 2");
2001 :
2002 :
2003 : /* query level 2, set level 3, query level 2 */
2004 :
2005 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2006 :
2007 0 : sd1 = info.info2.secdesc;
2008 :
2009 0 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 3, sd1), "");
2010 :
2011 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2012 :
2013 0 : sd2 = info.info2.secdesc;
2014 :
2015 0 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
2016 : "SD level 2 != SD level 2 after SD has been set via level 3");
2017 :
2018 : /* set modified sd level 3, query level 2 */
2019 :
2020 0 : for (i=0; i < 93; i++) {
2021 : struct security_ace a;
2022 0 : const char *sid_string = talloc_asprintf(tctx, "S-1-5-32-9999%i", i);
2023 0 : a.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
2024 0 : a.flags = 0;
2025 0 : a.size = 0; /* autogenerated */
2026 0 : a.access_mask = 0;
2027 0 : a.trustee = *dom_sid_parse_talloc(tctx, sid_string);
2028 0 : torture_assert_ntstatus_ok(tctx, security_descriptor_dacl_add(sd1, &a), "");
2029 : }
2030 :
2031 0 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 3, sd1), "");
2032 :
2033 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2034 0 : sd2 = info.info2.secdesc;
2035 :
2036 0 : if (sd1->type & SEC_DESC_DACL_DEFAULTED) {
2037 0 : torture_comment(tctx, "removing SEC_DESC_DACL_DEFAULTED\n");
2038 0 : sd1->type &= ~SEC_DESC_DACL_DEFAULTED;
2039 : }
2040 :
2041 0 : torture_assert(tctx, test_security_descriptor_equal(tctx, sd1, sd2),
2042 : "modified SD level 2 != SD level 2 after SD has been set via level 3");
2043 :
2044 :
2045 0 : return true;
2046 : }
2047 :
2048 : /*
2049 : * wrapper call that saves original sd, runs tests, and restores sd
2050 : */
2051 :
2052 0 : static bool test_PrinterInfo_SD(struct torture_context *tctx,
2053 : struct dcerpc_binding_handle *b,
2054 : struct policy_handle *handle)
2055 : {
2056 : union spoolss_PrinterInfo info;
2057 : struct security_descriptor *sd;
2058 0 : bool ret = true;
2059 :
2060 0 : torture_comment(tctx, "Testing Printer Security Descriptors\n");
2061 :
2062 : /* save original sd */
2063 :
2064 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
2065 : "failed to get initial security descriptor");
2066 :
2067 0 : sd = security_descriptor_copy(tctx, info.info2.secdesc);
2068 :
2069 : /* run tests */
2070 :
2071 0 : ret = test_PrinterInfo_SDs(tctx, b, handle);
2072 :
2073 : /* restore original sd */
2074 :
2075 0 : torture_assert(tctx, test_sd_set_level(tctx, b, handle, 3, sd),
2076 : "failed to restore initial security descriptor");
2077 :
2078 0 : torture_comment(tctx, "Printer Security Descriptors test %s\n\n",
2079 : ret ? "succeeded" : "failed");
2080 :
2081 :
2082 0 : return ret;
2083 : }
2084 :
2085 0 : static bool test_devmode_set_level(struct torture_context *tctx,
2086 : struct dcerpc_binding_handle *b,
2087 : struct policy_handle *handle,
2088 : uint32_t level,
2089 : struct spoolss_DeviceMode *devmode)
2090 : {
2091 : struct spoolss_SetPrinterInfoCtr info_ctr;
2092 : struct spoolss_DevmodeContainer devmode_ctr;
2093 : struct sec_desc_buf secdesc_ctr;
2094 : union spoolss_SetPrinterInfo sinfo;
2095 :
2096 0 : ZERO_STRUCT(devmode_ctr);
2097 0 : ZERO_STRUCT(secdesc_ctr);
2098 :
2099 0 : switch (level) {
2100 0 : case 2: {
2101 : union spoolss_PrinterInfo info;
2102 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2103 0 : torture_assert(tctx, PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
2104 :
2105 0 : info_ctr.level = 2;
2106 0 : info_ctr.info = sinfo;
2107 :
2108 0 : break;
2109 : }
2110 0 : case 8: {
2111 : struct spoolss_SetPrinterInfo8 info8;
2112 :
2113 0 : info8.devmode_ptr = 0;
2114 :
2115 0 : info_ctr.level = 8;
2116 0 : info_ctr.info.info8 = &info8;
2117 :
2118 0 : break;
2119 : }
2120 0 : default:
2121 0 : return false;
2122 : }
2123 :
2124 0 : devmode_ctr.devmode = devmode;
2125 :
2126 0 : torture_assert(tctx,
2127 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0), "");
2128 :
2129 0 : return true;
2130 : }
2131 :
2132 :
2133 0 : static bool test_devicemode_equal(struct torture_context *tctx,
2134 : const struct spoolss_DeviceMode *d1,
2135 : const struct spoolss_DeviceMode *d2)
2136 : {
2137 0 : if (d1 == d2) {
2138 0 : return true;
2139 : }
2140 :
2141 0 : if (!d1 || !d2) {
2142 0 : torture_comment(tctx, "%s\n", __location__);
2143 0 : return false;
2144 : }
2145 0 : torture_assert_str_equal(tctx, d1->devicename, d2->devicename, "devicename mismatch");
2146 0 : torture_assert_int_equal(tctx, d1->specversion, d2->specversion, "specversion mismatch");
2147 0 : torture_assert_int_equal(tctx, d1->driverversion, d2->driverversion, "driverversion mismatch");
2148 0 : torture_assert_int_equal(tctx, d1->size, d2->size, "size mismatch");
2149 0 : torture_assert_int_equal(tctx, d1->__driverextra_length, d2->__driverextra_length, "__driverextra_length mismatch");
2150 0 : torture_assert_int_equal(tctx, d1->fields, d2->fields, "fields mismatch");
2151 0 : torture_assert_int_equal(tctx, d1->orientation, d2->orientation, "orientation mismatch");
2152 0 : torture_assert_int_equal(tctx, d1->papersize, d2->papersize, "papersize mismatch");
2153 0 : torture_assert_int_equal(tctx, d1->paperlength, d2->paperlength, "paperlength mismatch");
2154 0 : torture_assert_int_equal(tctx, d1->paperwidth, d2->paperwidth, "paperwidth mismatch");
2155 0 : torture_assert_int_equal(tctx, d1->scale, d2->scale, "scale mismatch");
2156 0 : torture_assert_int_equal(tctx, d1->copies, d2->copies, "copies mismatch");
2157 0 : torture_assert_int_equal(tctx, d1->defaultsource, d2->defaultsource, "defaultsource mismatch");
2158 0 : torture_assert_int_equal(tctx, d1->printquality, d2->printquality, "printquality mismatch");
2159 0 : torture_assert_int_equal(tctx, d1->color, d2->color, "color mismatch");
2160 0 : torture_assert_int_equal(tctx, d1->duplex, d2->duplex, "duplex mismatch");
2161 0 : torture_assert_int_equal(tctx, d1->yresolution, d2->yresolution, "yresolution mismatch");
2162 0 : torture_assert_int_equal(tctx, d1->ttoption, d2->ttoption, "ttoption mismatch");
2163 0 : torture_assert_int_equal(tctx, d1->collate, d2->collate, "collate mismatch");
2164 0 : torture_assert_str_equal(tctx, d1->formname, d2->formname, "formname mismatch");
2165 0 : torture_assert_int_equal(tctx, d1->logpixels, d2->logpixels, "logpixels mismatch");
2166 0 : torture_assert_int_equal(tctx, d1->bitsperpel, d2->bitsperpel, "bitsperpel mismatch");
2167 0 : torture_assert_int_equal(tctx, d1->pelswidth, d2->pelswidth, "pelswidth mismatch");
2168 0 : torture_assert_int_equal(tctx, d1->pelsheight, d2->pelsheight, "pelsheight mismatch");
2169 0 : torture_assert_int_equal(tctx, d1->displayflags, d2->displayflags, "displayflags mismatch");
2170 0 : torture_assert_int_equal(tctx, d1->displayfrequency, d2->displayfrequency, "displayfrequency mismatch");
2171 0 : torture_assert_int_equal(tctx, d1->icmmethod, d2->icmmethod, "icmmethod mismatch");
2172 0 : torture_assert_int_equal(tctx, d1->icmintent, d2->icmintent, "icmintent mismatch");
2173 0 : torture_assert_int_equal(tctx, d1->mediatype, d2->mediatype, "mediatype mismatch");
2174 0 : torture_assert_int_equal(tctx, d1->dithertype, d2->dithertype, "dithertype mismatch");
2175 0 : torture_assert_int_equal(tctx, d1->reserved1, d2->reserved1, "reserved1 mismatch");
2176 0 : torture_assert_int_equal(tctx, d1->reserved2, d2->reserved2, "reserved2 mismatch");
2177 0 : torture_assert_int_equal(tctx, d1->panningwidth, d2->panningwidth, "panningwidth mismatch");
2178 0 : torture_assert_int_equal(tctx, d1->panningheight, d2->panningheight, "panningheight mismatch");
2179 0 : torture_assert_data_blob_equal(tctx, d1->driverextra_data, d2->driverextra_data, "driverextra_data mismatch");
2180 :
2181 0 : return true;
2182 : }
2183 :
2184 0 : static bool test_devicemode_full(struct torture_context *tctx,
2185 : struct dcerpc_binding_handle *b,
2186 : struct policy_handle *handle)
2187 : {
2188 : struct spoolss_SetPrinter s;
2189 : struct spoolss_GetPrinter q;
2190 : struct spoolss_SetPrinterInfoCtr info_ctr;
2191 : struct spoolss_SetPrinterInfo8 info8;
2192 : union spoolss_PrinterInfo info;
2193 : struct spoolss_DevmodeContainer devmode_ctr;
2194 : struct sec_desc_buf secdesc_ctr;
2195 : uint32_t needed;
2196 0 : bool ret = true;
2197 : NTSTATUS status;
2198 :
2199 : #define TEST_DEVMODE_INT_EXP_RESULT(lvl1, field1, lvl2, field2, value, exp_value, expected_result) do { \
2200 : torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
2201 : q.in.level = lvl1; \
2202 : TESTGETCALL(GetPrinter, q) \
2203 : info_ctr.level = lvl1; \
2204 : if (lvl1 == 2) {\
2205 : void *p = (void *)&q.out.info->info ## lvl1; \
2206 : info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)p; \
2207 : } else if (lvl1 == 8) {\
2208 : info_ctr.info.info ## lvl1 = &info8; \
2209 : }\
2210 : devmode_ctr.devmode = q.out.info->info ## lvl1.devmode; \
2211 : devmode_ctr.devmode->field1 = value; \
2212 : TESTSETCALL_EXP(SetPrinter, s, expected_result) \
2213 : if (W_ERROR_IS_OK(expected_result)) { \
2214 : TESTGETCALL(GetPrinter, q) \
2215 : INT_EQUAL(q.out.info->info ## lvl1.devmode->field1, exp_value, field1); \
2216 : q.in.level = lvl2; \
2217 : TESTGETCALL(GetPrinter, q) \
2218 : INT_EQUAL(q.out.info->info ## lvl2.devmode->field2, exp_value, field1); \
2219 : }\
2220 : } while (0)
2221 :
2222 : #define TEST_DEVMODE_INT_EXP(lvl1, field1, lvl2, field2, value, expected_result) do { \
2223 : TEST_DEVMODE_INT_EXP_RESULT(lvl1, field1, lvl2, field2, value, value, expected_result); \
2224 : } while (0)
2225 :
2226 : #define TEST_DEVMODE_INT(lvl1, field1, lvl2, field2, value) do { \
2227 : TEST_DEVMODE_INT_EXP_RESULT(lvl1, field1, lvl2, field2, value, value, WERR_OK); \
2228 : } while (0)
2229 :
2230 0 : ZERO_STRUCT(devmode_ctr);
2231 0 : ZERO_STRUCT(secdesc_ctr);
2232 0 : ZERO_STRUCT(info8);
2233 :
2234 0 : s.in.handle = handle;
2235 0 : s.in.command = 0;
2236 0 : s.in.info_ctr = &info_ctr;
2237 0 : s.in.devmode_ctr = &devmode_ctr;
2238 0 : s.in.secdesc_ctr = &secdesc_ctr;
2239 :
2240 0 : q.in.handle = handle;
2241 0 : q.out.info = &info;
2242 :
2243 : #if 0
2244 : const char *devicename;/* [charset(UTF16)] */
2245 : enum spoolss_DeviceModeSpecVersion specversion;
2246 : uint16_t driverversion;
2247 : uint16_t __driverextra_length;/* [value(r->driverextra_data.length)] */
2248 : uint32_t fields;
2249 : #endif
2250 0 : TEST_DEVMODE_INT_EXP(8, size, 8, size, __LINE__, WERR_INVALID_PARAMETER);
2251 0 : TEST_DEVMODE_INT_EXP(8, size, 8, size, 0, WERR_INVALID_PARAMETER);
2252 0 : TEST_DEVMODE_INT_EXP(8, size, 8, size, 0xffff, WERR_INVALID_PARAMETER);
2253 0 : TEST_DEVMODE_INT_EXP(8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0), (devmode_ctr.devmode->__driverextra_length > 0 ) ? WERR_INVALID_PARAMETER : WERR_OK);
2254 0 : TEST_DEVMODE_INT(8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0) - devmode_ctr.devmode->__driverextra_length);
2255 :
2256 0 : devmode_ctr.devmode->driverextra_data = data_blob_string_const("foobar");
2257 0 : torture_assert(tctx,
2258 : test_devmode_set_level(tctx, b, handle, 8, devmode_ctr.devmode),
2259 : "failed to set devmode");
2260 :
2261 0 : TEST_DEVMODE_INT_EXP(8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0), (devmode_ctr.devmode->__driverextra_length > 0 ) ? WERR_INVALID_PARAMETER : WERR_OK);
2262 0 : TEST_DEVMODE_INT(8, size, 8, size, ndr_size_spoolss_DeviceMode(devmode_ctr.devmode, 0) - devmode_ctr.devmode->__driverextra_length);
2263 :
2264 0 : TEST_DEVMODE_INT(8, orientation, 8, orientation, __LINE__);
2265 0 : TEST_DEVMODE_INT(8, papersize, 8, papersize, __LINE__);
2266 0 : TEST_DEVMODE_INT(8, paperlength, 8, paperlength, __LINE__);
2267 0 : TEST_DEVMODE_INT(8, paperwidth, 8, paperwidth, __LINE__);
2268 0 : TEST_DEVMODE_INT(8, scale, 8, scale, __LINE__);
2269 0 : TEST_DEVMODE_INT(8, copies, 8, copies, __LINE__);
2270 0 : TEST_DEVMODE_INT(8, defaultsource, 8, defaultsource, __LINE__);
2271 0 : TEST_DEVMODE_INT(8, printquality, 8, printquality, __LINE__);
2272 0 : TEST_DEVMODE_INT(8, color, 8, color, __LINE__);
2273 0 : TEST_DEVMODE_INT(8, duplex, 8, duplex, __LINE__);
2274 0 : TEST_DEVMODE_INT(8, yresolution, 8, yresolution, __LINE__);
2275 0 : TEST_DEVMODE_INT(8, ttoption, 8, ttoption, __LINE__);
2276 0 : TEST_DEVMODE_INT(8, collate, 8, collate, __LINE__);
2277 : #if 0
2278 : const char *formname;/* [charset(UTF16)] */
2279 : #endif
2280 0 : TEST_DEVMODE_INT(8, logpixels, 8, logpixels, __LINE__);
2281 0 : TEST_DEVMODE_INT(8, bitsperpel, 8, bitsperpel, __LINE__);
2282 0 : TEST_DEVMODE_INT(8, pelswidth, 8, pelswidth, __LINE__);
2283 0 : TEST_DEVMODE_INT(8, pelsheight, 8, pelsheight, __LINE__);
2284 0 : TEST_DEVMODE_INT(8, displayflags, 8, displayflags, __LINE__);
2285 0 : TEST_DEVMODE_INT(8, displayfrequency, 8, displayfrequency, __LINE__);
2286 0 : TEST_DEVMODE_INT(8, icmmethod, 8, icmmethod, __LINE__);
2287 0 : TEST_DEVMODE_INT(8, icmintent, 8, icmintent, __LINE__);
2288 0 : TEST_DEVMODE_INT(8, mediatype, 8, mediatype, __LINE__);
2289 0 : TEST_DEVMODE_INT(8, dithertype, 8, dithertype, __LINE__);
2290 0 : TEST_DEVMODE_INT(8, reserved1, 8, reserved1, __LINE__);
2291 0 : TEST_DEVMODE_INT(8, reserved2, 8, reserved2, __LINE__);
2292 0 : TEST_DEVMODE_INT(8, panningwidth, 8, panningwidth, __LINE__);
2293 0 : TEST_DEVMODE_INT(8, panningheight, 8, panningheight, __LINE__);
2294 :
2295 0 : return ret;
2296 : }
2297 :
2298 : static bool call_OpenPrinterEx(struct torture_context *tctx,
2299 : struct dcerpc_pipe *p,
2300 : const char *name,
2301 : struct spoolss_DeviceMode *devmode,
2302 : struct policy_handle *handle);
2303 :
2304 0 : static bool test_PrinterInfo_DevModes(struct torture_context *tctx,
2305 : struct dcerpc_pipe *p,
2306 : struct policy_handle *handle,
2307 : const char *name)
2308 : {
2309 : union spoolss_PrinterInfo info;
2310 : struct spoolss_DeviceMode *devmode;
2311 : struct spoolss_DeviceMode *devmode2;
2312 : struct policy_handle handle_devmode;
2313 0 : struct dcerpc_binding_handle *b = p->binding_handle;
2314 :
2315 : /* simply compare level8 and level2 devmode */
2316 :
2317 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info), "");
2318 :
2319 0 : devmode = info.info8.devmode;
2320 :
2321 0 : if (devmode && devmode->size == 0) {
2322 0 : torture_fail(tctx,
2323 : "devmode of zero size!");
2324 : }
2325 :
2326 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2327 :
2328 0 : devmode2 = info.info2.devmode;
2329 :
2330 0 : if (devmode2 && devmode2->size == 0) {
2331 0 : torture_fail(tctx,
2332 : "devmode of zero size!");
2333 : }
2334 :
2335 0 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2336 : "DM level 8 != DM level 2");
2337 :
2338 :
2339 : /* set devicemode level 8 and see if it persists */
2340 :
2341 0 : devmode->copies = 93;
2342 0 : devmode->formname = talloc_strdup(tctx, "Legal");
2343 :
2344 0 : torture_assert(tctx, test_devmode_set_level(tctx, b, handle, 8, devmode), "");
2345 :
2346 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info), "");
2347 :
2348 0 : devmode2 = info.info8.devmode;
2349 :
2350 0 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2351 : "modified DM level 8 != DM level 8 after DM has been set via level 8");
2352 :
2353 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2354 :
2355 0 : devmode2 = info.info2.devmode;
2356 :
2357 0 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2358 : "modified DM level 8 != DM level 2");
2359 :
2360 :
2361 : /* set devicemode level 2 and see if it persists */
2362 :
2363 0 : devmode->copies = 39;
2364 0 : devmode->formname = talloc_strdup(tctx, "Executive");
2365 :
2366 0 : torture_assert(tctx, test_devmode_set_level(tctx, b, handle, 2, devmode), "");
2367 :
2368 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info), "");
2369 :
2370 0 : devmode2 = info.info8.devmode;
2371 :
2372 0 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2373 : "modified DM level 8 != DM level 8 after DM has been set via level 2");
2374 :
2375 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info), "");
2376 :
2377 0 : devmode2 = info.info2.devmode;
2378 :
2379 0 : torture_assert(tctx, test_devicemode_equal(tctx, devmode, devmode2),
2380 : "modified DM level 8 != DM level 2");
2381 :
2382 :
2383 : /* check every single bit in public part of devicemode */
2384 :
2385 0 : torture_assert(tctx, test_devicemode_full(tctx, b, handle),
2386 : "failed to set every single devicemode component");
2387 :
2388 :
2389 : /* change formname upon open and see if it persists in getprinter calls */
2390 :
2391 0 : devmode->formname = talloc_strdup(tctx, "A4");
2392 0 : devmode->copies = 42;
2393 :
2394 0 : torture_assert(tctx, call_OpenPrinterEx(tctx, p, name, devmode, &handle_devmode),
2395 : "failed to open printer handle");
2396 :
2397 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, &handle_devmode, 8, &info), "");
2398 :
2399 0 : devmode2 = info.info8.devmode;
2400 :
2401 0 : if (strequal(devmode->devicename, devmode2->devicename)) {
2402 0 : torture_warning(tctx, "devicenames are the same\n");
2403 : } else {
2404 0 : torture_comment(tctx, "devicename passed in for open: %s\n", devmode->devicename);
2405 0 : torture_comment(tctx, "devicename after level 8 get: %s\n", devmode2->devicename);
2406 : }
2407 :
2408 0 : if (strequal(devmode->formname, devmode2->formname)) {
2409 0 : torture_warning(tctx, "formname are the same\n");
2410 : } else {
2411 0 : torture_comment(tctx, "formname passed in for open: %s\n", devmode->formname);
2412 0 : torture_comment(tctx, "formname after level 8 get: %s\n", devmode2->formname);
2413 : }
2414 :
2415 0 : if (devmode->copies == devmode2->copies) {
2416 0 : torture_warning(tctx, "copies are the same\n");
2417 : } else {
2418 0 : torture_comment(tctx, "copies passed in for open: %d\n", devmode->copies);
2419 0 : torture_comment(tctx, "copies after level 8 get: %d\n", devmode2->copies);
2420 : }
2421 :
2422 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, &handle_devmode, 2, &info), "");
2423 :
2424 0 : devmode2 = info.info2.devmode;
2425 :
2426 0 : if (strequal(devmode->devicename, devmode2->devicename)) {
2427 0 : torture_warning(tctx, "devicenames are the same\n");
2428 : } else {
2429 0 : torture_comment(tctx, "devicename passed in for open: %s\n", devmode->devicename);
2430 0 : torture_comment(tctx, "devicename after level 2 get: %s\n", devmode2->devicename);
2431 : }
2432 :
2433 0 : if (strequal(devmode->formname, devmode2->formname)) {
2434 0 : torture_warning(tctx, "formname is the same\n");
2435 : } else {
2436 0 : torture_comment(tctx, "formname passed in for open: %s\n", devmode->formname);
2437 0 : torture_comment(tctx, "formname after level 2 get: %s\n", devmode2->formname);
2438 : }
2439 :
2440 0 : if (devmode->copies == devmode2->copies) {
2441 0 : torture_warning(tctx, "copies are the same\n");
2442 : } else {
2443 0 : torture_comment(tctx, "copies passed in for open: %d\n", devmode->copies);
2444 0 : torture_comment(tctx, "copies after level 2 get: %d\n", devmode2->copies);
2445 : }
2446 :
2447 0 : test_ClosePrinter(tctx, b, &handle_devmode);
2448 :
2449 0 : return true;
2450 : }
2451 :
2452 : /*
2453 : * wrapper call that saves original devmode, runs tests, and restores devmode
2454 : */
2455 :
2456 0 : static bool test_PrinterInfo_DevMode(struct torture_context *tctx,
2457 : struct dcerpc_pipe *p,
2458 : struct policy_handle *handle,
2459 : const char *name,
2460 : struct spoolss_DeviceMode *addprinter_devmode)
2461 : {
2462 : union spoolss_PrinterInfo info;
2463 : struct spoolss_DeviceMode *devmode;
2464 0 : bool ret = true;
2465 0 : struct dcerpc_binding_handle *b = p->binding_handle;
2466 :
2467 0 : torture_comment(tctx, "Testing Printer Devicemodes\n");
2468 :
2469 : /* save original devmode */
2470 :
2471 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 8, &info),
2472 : "failed to get initial global devicemode");
2473 :
2474 0 : devmode = info.info8.devmode;
2475 :
2476 0 : if (devmode && devmode->size == 0) {
2477 0 : torture_fail(tctx,
2478 : "devmode of zero size!");
2479 : }
2480 :
2481 0 : if (addprinter_devmode) {
2482 0 : if (!test_devicemode_equal(tctx, devmode, addprinter_devmode)) {
2483 0 : torture_warning(tctx, "current global DM is != DM provided in addprinter");
2484 : }
2485 : }
2486 :
2487 : /* run tests */
2488 :
2489 0 : ret = test_PrinterInfo_DevModes(tctx, p, handle, name);
2490 :
2491 : /* restore original devmode */
2492 :
2493 0 : torture_assert(tctx, test_devmode_set_level(tctx, b, handle, 8, devmode),
2494 : "failed to restore initial global device mode");
2495 :
2496 0 : torture_comment(tctx, "Printer Devicemodes test %s\n\n",
2497 : ret ? "succeeded" : "failed");
2498 :
2499 :
2500 0 : return ret;
2501 : }
2502 :
2503 2 : bool test_ClosePrinter(struct torture_context *tctx,
2504 : struct dcerpc_binding_handle *b,
2505 : struct policy_handle *handle)
2506 : {
2507 : NTSTATUS status;
2508 : struct spoolss_ClosePrinter r;
2509 :
2510 2 : r.in.handle = handle;
2511 2 : r.out.handle = handle;
2512 :
2513 2 : torture_comment(tctx, "Testing ClosePrinter\n");
2514 :
2515 2 : status = dcerpc_spoolss_ClosePrinter_r(b, tctx, &r);
2516 2 : torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
2517 2 : torture_assert_werr_ok(tctx, r.out.result, "ClosePrinter failed");
2518 :
2519 2 : return true;
2520 : }
2521 :
2522 0 : static bool test_GetForm_args(struct torture_context *tctx,
2523 : struct dcerpc_binding_handle *b,
2524 : struct policy_handle *handle,
2525 : const char *form_name,
2526 : uint32_t level,
2527 : union spoolss_FormInfo *info_p)
2528 : {
2529 : NTSTATUS status;
2530 : struct spoolss_GetForm r;
2531 : uint32_t needed;
2532 :
2533 0 : r.in.handle = handle;
2534 0 : r.in.form_name = form_name;
2535 0 : r.in.level = level;
2536 0 : r.in.buffer = NULL;
2537 0 : r.in.offered = 0;
2538 0 : r.out.needed = &needed;
2539 :
2540 0 : torture_comment(tctx, "Testing GetForm(%s) level %d\n", form_name, r.in.level);
2541 :
2542 0 : status = dcerpc_spoolss_GetForm_r(b, tctx, &r);
2543 0 : torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
2544 :
2545 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2546 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
2547 0 : r.in.buffer = &blob;
2548 0 : r.in.offered = needed;
2549 0 : status = dcerpc_spoolss_GetForm_r(b, tctx, &r);
2550 0 : torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
2551 :
2552 0 : torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
2553 :
2554 0 : torture_assert(tctx, r.out.info, "No form info returned");
2555 : }
2556 :
2557 0 : torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
2558 :
2559 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_FormInfo, r.out.info, r.in.level, needed, 4);
2560 :
2561 0 : if (info_p) {
2562 0 : *info_p = *r.out.info;
2563 : }
2564 :
2565 0 : return true;
2566 : }
2567 :
2568 0 : static bool test_GetForm(struct torture_context *tctx,
2569 : struct dcerpc_binding_handle *b,
2570 : struct policy_handle *handle,
2571 : const char *form_name,
2572 : uint32_t level)
2573 : {
2574 0 : return test_GetForm_args(tctx, b, handle, form_name, level, NULL);
2575 : }
2576 :
2577 0 : static bool test_EnumForms(struct torture_context *tctx,
2578 : struct dcerpc_binding_handle *b,
2579 : struct policy_handle *handle,
2580 : bool print_server,
2581 : uint32_t level,
2582 : uint32_t *count_p,
2583 : union spoolss_FormInfo **info_p)
2584 : {
2585 : struct spoolss_EnumForms r;
2586 : uint32_t needed;
2587 : uint32_t count;
2588 : union spoolss_FormInfo *info;
2589 :
2590 0 : r.in.handle = handle;
2591 0 : r.in.level = level;
2592 0 : r.in.buffer = NULL;
2593 0 : r.in.offered = 0;
2594 0 : r.out.needed = &needed;
2595 0 : r.out.count = &count;
2596 0 : r.out.info = &info;
2597 :
2598 0 : torture_comment(tctx, "Testing EnumForms level %d\n", r.in.level);
2599 :
2600 0 : torture_assert_ntstatus_ok(tctx,
2601 : dcerpc_spoolss_EnumForms_r(b, tctx, &r),
2602 : "EnumForms failed");
2603 :
2604 0 : if ((r.in.level == 2) && (W_ERROR_EQUAL(r.out.result, WERR_INVALID_LEVEL))) {
2605 0 : torture_skip(tctx, "EnumForms level 2 not supported");
2606 : }
2607 :
2608 0 : if (print_server && W_ERROR_EQUAL(r.out.result, WERR_INVALID_HANDLE)) {
2609 0 : torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)");
2610 : }
2611 :
2612 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2613 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
2614 0 : r.in.buffer = &blob;
2615 0 : r.in.offered = needed;
2616 :
2617 0 : torture_assert_ntstatus_ok(tctx,
2618 : dcerpc_spoolss_EnumForms_r(b, tctx, &r),
2619 : "EnumForms failed");
2620 :
2621 0 : torture_assert(tctx, info, "No forms returned");
2622 : }
2623 :
2624 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
2625 :
2626 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumForms, info, r.in.level, count, needed, 4);
2627 :
2628 0 : if (info_p) {
2629 0 : *info_p = info;
2630 : }
2631 0 : if (count_p) {
2632 0 : *count_p = count;
2633 : }
2634 :
2635 0 : return true;
2636 : }
2637 :
2638 0 : static bool test_EnumForms_all(struct torture_context *tctx,
2639 : struct dcerpc_binding_handle *b,
2640 : struct policy_handle *handle,
2641 : bool print_server)
2642 : {
2643 0 : uint32_t levels[] = { 1, 2 };
2644 : int i, j;
2645 :
2646 0 : for (i=0; i<ARRAY_SIZE(levels); i++) {
2647 :
2648 0 : uint32_t count = 0;
2649 0 : union spoolss_FormInfo *info = NULL;
2650 :
2651 0 : torture_assert(tctx,
2652 : test_EnumForms(tctx, b, handle, print_server, levels[i], &count, &info),
2653 : "failed to enum forms");
2654 :
2655 0 : for (j = 0; j < count; j++) {
2656 0 : if (!print_server) {
2657 0 : torture_assert(tctx,
2658 : test_GetForm(tctx, b, handle, info[j].info1.form_name, levels[i]),
2659 : "failed to get form");
2660 : }
2661 : }
2662 : }
2663 :
2664 0 : return true;
2665 : }
2666 :
2667 0 : static bool test_EnumForms_find_one(struct torture_context *tctx,
2668 : struct dcerpc_binding_handle *b,
2669 : struct policy_handle *handle,
2670 : bool print_server,
2671 : const char *form_name)
2672 : {
2673 0 : union spoolss_FormInfo *info = NULL;
2674 0 : uint32_t count = 0;
2675 0 : bool found = false;
2676 : int i;
2677 :
2678 0 : torture_assert(tctx,
2679 : test_EnumForms(tctx, b, handle, print_server, 1, &count, &info),
2680 : "failed to enumerate forms");
2681 :
2682 0 : for (i=0; i<count; i++) {
2683 0 : if (strequal(form_name, info[i].info1.form_name)) {
2684 0 : found = true;
2685 0 : break;
2686 : }
2687 : }
2688 :
2689 0 : return found;
2690 : }
2691 :
2692 0 : static bool test_DeleteForm(struct torture_context *tctx,
2693 : struct dcerpc_binding_handle *b,
2694 : struct policy_handle *handle,
2695 : const char *form_name,
2696 : WERROR expected_result)
2697 : {
2698 : struct spoolss_DeleteForm r;
2699 :
2700 0 : r.in.handle = handle;
2701 0 : r.in.form_name = form_name;
2702 :
2703 0 : torture_comment(tctx, "Testing DeleteForm(%s)\n", form_name);
2704 :
2705 0 : torture_assert_ntstatus_ok(tctx,
2706 : dcerpc_spoolss_DeleteForm_r(b, tctx, &r),
2707 : "DeleteForm failed");
2708 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
2709 : "DeleteForm gave unexpected result");
2710 0 : if (W_ERROR_IS_OK(r.out.result)) {
2711 0 : torture_assert_ntstatus_ok(tctx,
2712 : dcerpc_spoolss_DeleteForm_r(b, tctx, &r),
2713 : "2nd DeleteForm failed");
2714 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_FORM_NAME,
2715 : "2nd DeleteForm failed");
2716 : }
2717 :
2718 0 : return true;
2719 : }
2720 :
2721 0 : static bool test_AddForm(struct torture_context *tctx,
2722 : struct dcerpc_binding_handle *b,
2723 : struct policy_handle *handle,
2724 : uint32_t level,
2725 : union spoolss_AddFormInfo *info,
2726 : WERROR expected_result)
2727 : {
2728 : struct spoolss_AddForm r;
2729 : struct spoolss_AddFormInfoCtr info_ctr;
2730 :
2731 0 : info_ctr.level = level;
2732 0 : info_ctr.info = *info;
2733 :
2734 0 : if (level != 1) {
2735 0 : torture_skip(tctx, "only level 1 supported");
2736 : }
2737 :
2738 0 : r.in.handle = handle;
2739 0 : r.in.info_ctr = &info_ctr;
2740 :
2741 0 : torture_comment(tctx, "Testing AddForm(%s) level %d, type %d\n",
2742 0 : r.in.info_ctr->info.info1->form_name, level,
2743 0 : r.in.info_ctr->info.info1->flags);
2744 :
2745 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_AddForm_r(b, tctx, &r),
2746 : "AddForm failed");
2747 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
2748 : "AddForm gave unexpected result");
2749 :
2750 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_AddForm_r(b, tctx, &r),
2751 : "2nd AddForm failed");
2752 0 : if (W_ERROR_EQUAL(expected_result, WERR_INVALID_PARAMETER)) {
2753 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2754 : "2nd AddForm gave unexpected result");
2755 : } else {
2756 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_FILE_EXISTS,
2757 : "2nd AddForm gave unexpected result");
2758 : }
2759 :
2760 0 : return true;
2761 : }
2762 :
2763 0 : static bool test_SetForm(struct torture_context *tctx,
2764 : struct dcerpc_binding_handle *b,
2765 : struct policy_handle *handle,
2766 : const char *form_name,
2767 : uint32_t level,
2768 : union spoolss_AddFormInfo *info)
2769 : {
2770 : struct spoolss_SetForm r;
2771 : struct spoolss_AddFormInfoCtr info_ctr;
2772 :
2773 0 : info_ctr.level = level;
2774 0 : info_ctr.info = *info;
2775 :
2776 0 : r.in.handle = handle;
2777 0 : r.in.form_name = form_name;
2778 0 : r.in.info_ctr = &info_ctr;
2779 :
2780 0 : torture_comment(tctx, "Testing SetForm(%s) level %d\n",
2781 : form_name, level);
2782 :
2783 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetForm_r(b, tctx, &r),
2784 : "SetForm failed");
2785 :
2786 0 : torture_assert_werr_ok(tctx, r.out.result,
2787 : "SetForm failed");
2788 :
2789 0 : return true;
2790 : }
2791 :
2792 : static bool test_GetForm_winreg(struct torture_context *tctx,
2793 : struct dcerpc_binding_handle *b,
2794 : struct policy_handle *handle,
2795 : const char *key_name,
2796 : const char *form_name,
2797 : enum winreg_Type *w_type,
2798 : uint32_t *w_size,
2799 : uint32_t *w_length,
2800 : uint8_t **w_data);
2801 :
2802 0 : static bool test_Forms_args(struct torture_context *tctx,
2803 : struct dcerpc_binding_handle *b,
2804 : struct policy_handle *handle,
2805 : bool print_server,
2806 : const char *printer_name,
2807 : struct dcerpc_binding_handle *winreg_handle,
2808 : struct policy_handle *hive_handle,
2809 : const char *form_name,
2810 : struct spoolss_AddFormInfo1 *info1,
2811 : WERROR expected_add_result,
2812 : WERROR expected_delete_result)
2813 : {
2814 : union spoolss_FormInfo info;
2815 : union spoolss_AddFormInfo add_info;
2816 :
2817 : enum winreg_Type w_type;
2818 : uint32_t w_size;
2819 : uint32_t w_length;
2820 : uint8_t *w_data;
2821 :
2822 0 : add_info.info1 = info1;
2823 :
2824 0 : torture_assert(tctx,
2825 : test_AddForm(tctx, b, handle, 1, &add_info, expected_add_result),
2826 : "failed to add form");
2827 :
2828 0 : if (winreg_handle && hive_handle && W_ERROR_IS_OK(expected_add_result)) {
2829 :
2830 : struct spoolss_FormInfo1 i1;
2831 :
2832 0 : torture_assert(tctx,
2833 : test_GetForm_winreg(tctx, winreg_handle, hive_handle, TOP_LEVEL_CONTROL_FORMS_KEY, form_name, &w_type, &w_size, &w_length, &w_data),
2834 : "failed to get form via winreg");
2835 :
2836 0 : i1.size.width = IVAL(w_data, 0);
2837 0 : i1.size.height = IVAL(w_data, 4);
2838 0 : i1.area.left = IVAL(w_data, 8);
2839 0 : i1.area.top = IVAL(w_data, 12);
2840 0 : i1.area.right = IVAL(w_data, 16);
2841 0 : i1.area.bottom = IVAL(w_data, 20);
2842 : /* skip index here */
2843 0 : i1.flags = IVAL(w_data, 28);
2844 :
2845 0 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");
2846 0 : torture_assert_int_equal(tctx, w_size, 0x20, "unexpected size");
2847 0 : torture_assert_int_equal(tctx, w_length, 0x20, "unexpected length");
2848 0 : torture_assert_int_equal(tctx, i1.size.width, add_info.info1->size.width, "width mismatch");
2849 0 : torture_assert_int_equal(tctx, i1.size.height, add_info.info1->size.height, "height mismatch");
2850 0 : torture_assert_int_equal(tctx, i1.area.left, add_info.info1->area.left, "left mismatch");
2851 0 : torture_assert_int_equal(tctx, i1.area.top, add_info.info1->area.top, "top mismatch");
2852 0 : torture_assert_int_equal(tctx, i1.area.right, add_info.info1->area.right, "right mismatch");
2853 0 : torture_assert_int_equal(tctx, i1.area.bottom, add_info.info1->area.bottom, "bottom mismatch");
2854 0 : torture_assert_int_equal(tctx, i1.flags, add_info.info1->flags, "flags mismatch");
2855 : }
2856 :
2857 0 : if (!print_server && W_ERROR_IS_OK(expected_add_result)) {
2858 0 : torture_assert(tctx,
2859 : test_GetForm_args(tctx, b, handle, form_name, 1, &info),
2860 : "failed to get added form");
2861 :
2862 0 : torture_assert_int_equal(tctx, info.info1.size.width, add_info.info1->size.width, "width mismatch");
2863 0 : torture_assert_int_equal(tctx, info.info1.size.height, add_info.info1->size.height, "height mismatch");
2864 0 : torture_assert_int_equal(tctx, info.info1.area.left, add_info.info1->area.left, "left mismatch");
2865 0 : torture_assert_int_equal(tctx, info.info1.area.top, add_info.info1->area.top, "top mismatch");
2866 0 : torture_assert_int_equal(tctx, info.info1.area.right, add_info.info1->area.right, "right mismatch");
2867 0 : torture_assert_int_equal(tctx, info.info1.area.bottom, add_info.info1->area.bottom, "bottom mismatch");
2868 0 : torture_assert_int_equal(tctx, info.info1.flags, add_info.info1->flags, "flags mismatch");
2869 :
2870 0 : if (winreg_handle && hive_handle) {
2871 :
2872 : struct spoolss_FormInfo1 i1;
2873 :
2874 0 : i1.size.width = IVAL(w_data, 0);
2875 0 : i1.size.height = IVAL(w_data, 4);
2876 0 : i1.area.left = IVAL(w_data, 8);
2877 0 : i1.area.top = IVAL(w_data, 12);
2878 0 : i1.area.right = IVAL(w_data, 16);
2879 0 : i1.area.bottom = IVAL(w_data, 20);
2880 : /* skip index here */
2881 0 : i1.flags = IVAL(w_data, 28);
2882 :
2883 0 : torture_assert_int_equal(tctx, i1.size.width, info.info1.size.width, "width mismatch");
2884 0 : torture_assert_int_equal(tctx, i1.size.height, info.info1.size.height, "height mismatch");
2885 0 : torture_assert_int_equal(tctx, i1.area.left, info.info1.area.left, "left mismatch");
2886 0 : torture_assert_int_equal(tctx, i1.area.top, info.info1.area.top, "top mismatch");
2887 0 : torture_assert_int_equal(tctx, i1.area.right, info.info1.area.right, "right mismatch");
2888 0 : torture_assert_int_equal(tctx, i1.area.bottom, info.info1.area.bottom, "bottom mismatch");
2889 0 : torture_assert_int_equal(tctx, i1.flags, info.info1.flags, "flags mismatch");
2890 : }
2891 :
2892 0 : add_info.info1->size.width = 1234;
2893 :
2894 0 : torture_assert(tctx,
2895 : test_SetForm(tctx, b, handle, form_name, 1, &add_info),
2896 : "failed to set form");
2897 0 : torture_assert(tctx,
2898 : test_GetForm_args(tctx, b, handle, form_name, 1, &info),
2899 : "failed to get set form");
2900 :
2901 0 : torture_assert_int_equal(tctx, info.info1.size.width, add_info.info1->size.width, "width mismatch");
2902 : }
2903 :
2904 0 : if (!W_ERROR_EQUAL(expected_add_result, WERR_INVALID_PARAMETER)) {
2905 0 : torture_assert(tctx,
2906 : test_EnumForms_find_one(tctx, b, handle, print_server, form_name),
2907 : "Newly added form not found in enum call");
2908 : }
2909 :
2910 0 : torture_assert(tctx,
2911 : test_DeleteForm(tctx, b, handle, form_name, expected_delete_result),
2912 : "failed to delete form");
2913 :
2914 0 : return true;
2915 : }
2916 :
2917 0 : static bool test_Forms(struct torture_context *tctx,
2918 : struct dcerpc_binding_handle *b,
2919 : struct policy_handle *handle,
2920 : bool print_server,
2921 : const char *printer_name,
2922 : struct dcerpc_binding_handle *winreg_handle,
2923 : struct policy_handle *hive_handle)
2924 : {
2925 : const struct spoolss_FormSize size = {
2926 : .width = 50,
2927 : .height = 25
2928 : };
2929 : const struct spoolss_FormArea area = {
2930 : .left = 5,
2931 : .top = 10,
2932 : .right = 45,
2933 : .bottom = 15
2934 : };
2935 : int i;
2936 :
2937 : struct {
2938 : struct spoolss_AddFormInfo1 info1;
2939 : WERROR expected_add_result;
2940 : WERROR expected_delete_result;
2941 0 : } forms[] = {
2942 : {
2943 : .info1 = {
2944 : .flags = SPOOLSS_FORM_USER,
2945 : .form_name = "testform_user",
2946 : .size = size,
2947 : .area = area,
2948 : },
2949 : .expected_add_result = WERR_OK,
2950 : .expected_delete_result = WERR_OK
2951 : },
2952 : /*
2953 : weird, we can add a builtin form but we can never remove it
2954 : again - gd
2955 :
2956 : {
2957 : .info1 = {
2958 : .flags = SPOOLSS_FORM_BUILTIN,
2959 : .form_name = "testform_builtin",
2960 : .size = size,
2961 : .area = area,
2962 : },
2963 : .expected_add_result = WERR_OK,
2964 : .expected_delete_result = WERR_INVALID_PARAMETER,
2965 : },
2966 : */
2967 : {
2968 : .info1 = {
2969 : .flags = SPOOLSS_FORM_PRINTER,
2970 : .form_name = "testform_printer",
2971 : .size = size,
2972 : .area = area,
2973 : },
2974 : .expected_add_result = WERR_OK,
2975 : .expected_delete_result = WERR_OK
2976 : },
2977 : {
2978 : .info1 = {
2979 : .flags = SPOOLSS_FORM_USER,
2980 : .form_name = "Letter",
2981 : .size = size,
2982 : .area = area,
2983 : },
2984 : .expected_add_result = WERR_FILE_EXISTS,
2985 : .expected_delete_result = WERR_INVALID_PARAMETER
2986 : },
2987 : {
2988 : .info1 = {
2989 : .flags = SPOOLSS_FORM_BUILTIN,
2990 : .form_name = "Letter",
2991 : .size = size,
2992 : .area = area,
2993 : },
2994 : .expected_add_result = WERR_FILE_EXISTS,
2995 : .expected_delete_result = WERR_INVALID_PARAMETER
2996 : },
2997 : {
2998 : .info1 = {
2999 : .flags = SPOOLSS_FORM_PRINTER,
3000 : .form_name = "Letter",
3001 : .size = size,
3002 : .area = area,
3003 : },
3004 : .expected_add_result = WERR_FILE_EXISTS,
3005 : .expected_delete_result = WERR_INVALID_PARAMETER
3006 : },
3007 : {
3008 : .info1 = {
3009 : .flags = 12345,
3010 : .form_name = "invalid_flags",
3011 : .size = size,
3012 : .area = area,
3013 : },
3014 : .expected_add_result = WERR_INVALID_PARAMETER,
3015 : .expected_delete_result = WERR_INVALID_FORM_NAME
3016 : }
3017 :
3018 : };
3019 :
3020 0 : for (i=0; i < ARRAY_SIZE(forms); i++) {
3021 0 : torture_assert(tctx,
3022 : test_Forms_args(tctx, b, handle, print_server, printer_name,
3023 : winreg_handle, hive_handle,
3024 : forms[i].info1.form_name,
3025 : &forms[i].info1,
3026 : forms[i].expected_add_result,
3027 : forms[i].expected_delete_result),
3028 : talloc_asprintf(tctx, "failed to test form '%s'", forms[i].info1.form_name));
3029 : }
3030 :
3031 0 : return true;
3032 : }
3033 :
3034 0 : static bool test_EnumPorts_old(struct torture_context *tctx,
3035 : void *private_data)
3036 : {
3037 0 : struct test_spoolss_context *ctx =
3038 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
3039 :
3040 : NTSTATUS status;
3041 : struct spoolss_EnumPorts r;
3042 : uint32_t needed;
3043 : uint32_t count;
3044 : union spoolss_PortInfo *info;
3045 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
3046 0 : struct dcerpc_binding_handle *b = p->binding_handle;
3047 :
3048 0 : r.in.servername = talloc_asprintf(tctx, "\\\\%s",
3049 : dcerpc_server_name(p));
3050 0 : r.in.level = 2;
3051 0 : r.in.buffer = NULL;
3052 0 : r.in.offered = 0;
3053 0 : r.out.needed = &needed;
3054 0 : r.out.count = &count;
3055 0 : r.out.info = &info;
3056 :
3057 0 : torture_comment(tctx, "Testing EnumPorts\n");
3058 :
3059 0 : status = dcerpc_spoolss_EnumPorts_r(b, tctx, &r);
3060 :
3061 0 : torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
3062 :
3063 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3064 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
3065 0 : r.in.buffer = &blob;
3066 0 : r.in.offered = needed;
3067 :
3068 0 : status = dcerpc_spoolss_EnumPorts_r(b, tctx, &r);
3069 0 : torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
3070 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
3071 :
3072 0 : torture_assert(tctx, info, "No ports returned");
3073 : }
3074 :
3075 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
3076 :
3077 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, 2, count, needed, 4);
3078 :
3079 0 : return true;
3080 : }
3081 :
3082 0 : static bool test_AddPort(struct torture_context *tctx,
3083 : void *private_data)
3084 : {
3085 0 : struct test_spoolss_context *ctx =
3086 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
3087 :
3088 : NTSTATUS status;
3089 : struct spoolss_AddPort r;
3090 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
3091 0 : struct dcerpc_binding_handle *b = p->binding_handle;
3092 :
3093 0 : r.in.server_name = talloc_asprintf(tctx, "\\\\%s",
3094 : dcerpc_server_name(p));
3095 0 : r.in.unknown = 0;
3096 0 : r.in.monitor_name = "foo";
3097 :
3098 0 : torture_comment(tctx, "Testing AddPort\n");
3099 :
3100 0 : status = dcerpc_spoolss_AddPort_r(b, tctx, &r);
3101 :
3102 0 : torture_assert_ntstatus_ok(tctx, status, "AddPort failed");
3103 :
3104 : /* win2k3 returns WERR_NOT_SUPPORTED */
3105 :
3106 : #if 0
3107 :
3108 : if (!W_ERROR_IS_OK(r.out.result)) {
3109 : printf("AddPort failed - %s\n", win_errstr(r.out.result));
3110 : return false;
3111 : }
3112 :
3113 : #endif
3114 :
3115 0 : return true;
3116 : }
3117 :
3118 0 : static bool test_GetJob_args(struct torture_context *tctx,
3119 : struct dcerpc_binding_handle *b,
3120 : struct policy_handle *handle,
3121 : uint32_t job_id,
3122 : uint32_t level,
3123 : union spoolss_JobInfo *info_p)
3124 : {
3125 : NTSTATUS status;
3126 : struct spoolss_GetJob r;
3127 : union spoolss_JobInfo info;
3128 : uint32_t needed;
3129 :
3130 0 : r.in.handle = handle;
3131 0 : r.in.job_id = job_id;
3132 0 : r.in.level = level;
3133 0 : r.in.buffer = NULL;
3134 0 : r.in.offered = 0;
3135 0 : r.out.needed = &needed;
3136 0 : r.out.info = &info;
3137 :
3138 0 : torture_comment(tctx, "Testing GetJob(%d), level %d\n", job_id, r.in.level);
3139 :
3140 0 : status = dcerpc_spoolss_GetJob_r(b, tctx, &r);
3141 0 : torture_assert_ntstatus_ok(tctx, status, "GetJob failed");
3142 0 : if (level == 0) {
3143 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "Unexpected return code");
3144 : }
3145 :
3146 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3147 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
3148 0 : r.in.buffer = &blob;
3149 0 : r.in.offered = needed;
3150 :
3151 0 : status = dcerpc_spoolss_GetJob_r(b, tctx, &r);
3152 0 : torture_assert_ntstatus_ok(tctx, status, "GetJob failed");
3153 : }
3154 :
3155 0 : torture_assert_werr_ok(tctx, r.out.result, "GetJob failed");
3156 0 : torture_assert(tctx, r.out.info, "No job info returned");
3157 :
3158 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_JobInfo, r.out.info, r.in.level, needed, 4);
3159 :
3160 0 : if (info_p) {
3161 0 : *info_p = *r.out.info;
3162 : }
3163 :
3164 0 : return true;
3165 : }
3166 :
3167 : #if 0
3168 : static bool test_GetJob(struct torture_context *tctx,
3169 : struct dcerpc_binding_handle *b,
3170 : struct policy_handle *handle,
3171 : uint32_t job_id)
3172 : {
3173 : uint32_t levels[] = {0, 1, 2 /* 3, 4 */};
3174 : uint32_t i;
3175 :
3176 : for (i=0; i < ARRAY_SIZE(levels); i++) {
3177 : torture_assert(tctx,
3178 : test_GetJob_args(tctx, b, handle, job_id, levels[i], NULL),
3179 : "GetJob failed");
3180 : }
3181 :
3182 : return true;
3183 : }
3184 : #endif
3185 :
3186 0 : static bool test_SetJob(struct torture_context *tctx,
3187 : struct dcerpc_binding_handle *b,
3188 : struct policy_handle *handle,
3189 : uint32_t job_id,
3190 : struct spoolss_JobInfoContainer *ctr,
3191 : enum spoolss_JobControl command)
3192 : {
3193 : NTSTATUS status;
3194 : struct spoolss_SetJob r;
3195 :
3196 0 : r.in.handle = handle;
3197 0 : r.in.job_id = job_id;
3198 0 : r.in.ctr = ctr;
3199 0 : r.in.command = command;
3200 :
3201 0 : switch (command) {
3202 0 : case SPOOLSS_JOB_CONTROL_PAUSE:
3203 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_PAUSE\n", job_id);
3204 0 : break;
3205 0 : case SPOOLSS_JOB_CONTROL_RESUME:
3206 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESUME\n", job_id);
3207 0 : break;
3208 0 : case SPOOLSS_JOB_CONTROL_CANCEL:
3209 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_CANCEL\n", job_id);
3210 0 : break;
3211 0 : case SPOOLSS_JOB_CONTROL_RESTART:
3212 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RESTART\n", job_id);
3213 0 : break;
3214 0 : case SPOOLSS_JOB_CONTROL_DELETE:
3215 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_DELETE\n", job_id);
3216 0 : break;
3217 0 : case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER:
3218 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER\n", job_id);
3219 0 : break;
3220 0 : case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED:
3221 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED\n", job_id);
3222 0 : break;
3223 0 : case SPOOLSS_JOB_CONTROL_RETAIN:
3224 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RETAIN\n", job_id);
3225 0 : break;
3226 0 : case SPOOLSS_JOB_CONTROL_RELEASE:
3227 0 : torture_comment(tctx, "Testing SetJob(%d), SPOOLSS_JOB_CONTROL_RELEASE\n", job_id);
3228 0 : break;
3229 0 : default:
3230 0 : torture_comment(tctx, "Testing SetJob(%d)\n", job_id);
3231 0 : break;
3232 : }
3233 :
3234 0 : status = dcerpc_spoolss_SetJob_r(b, tctx, &r);
3235 0 : torture_assert_ntstatus_ok(tctx, status, "SetJob failed");
3236 0 : torture_assert_werr_ok(tctx, r.out.result, "SetJob failed");
3237 :
3238 0 : return true;
3239 : }
3240 :
3241 0 : static bool test_AddJob(struct torture_context *tctx,
3242 : struct dcerpc_binding_handle *b,
3243 : struct policy_handle *handle)
3244 : {
3245 : NTSTATUS status;
3246 : struct spoolss_AddJob r;
3247 : uint32_t needed;
3248 :
3249 0 : r.in.level = 0;
3250 0 : r.in.handle = handle;
3251 0 : r.in.offered = 0;
3252 0 : r.out.needed = &needed;
3253 0 : r.in.buffer = r.out.buffer = NULL;
3254 :
3255 0 : torture_comment(tctx, "Testing AddJob\n");
3256 :
3257 0 : status = dcerpc_spoolss_AddJob_r(b, tctx, &r);
3258 0 : torture_assert_ntstatus_ok(tctx, status, "AddJob failed");
3259 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "AddJob failed");
3260 :
3261 0 : r.in.level = 1;
3262 :
3263 0 : status = dcerpc_spoolss_AddJob_r(b, tctx, &r);
3264 0 : torture_assert_ntstatus_ok(tctx, status, "AddJob failed");
3265 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER, "AddJob failed");
3266 :
3267 0 : return true;
3268 : }
3269 :
3270 :
3271 0 : static bool test_EnumJobs_args(struct torture_context *tctx,
3272 : struct dcerpc_binding_handle *b,
3273 : struct policy_handle *handle,
3274 : uint32_t level,
3275 : WERROR werr_expected,
3276 : uint32_t *count_p,
3277 : union spoolss_JobInfo **info_p)
3278 : {
3279 : NTSTATUS status;
3280 : struct spoolss_EnumJobs r;
3281 : uint32_t needed;
3282 : uint32_t count;
3283 : union spoolss_JobInfo *info;
3284 :
3285 0 : r.in.handle = handle;
3286 0 : r.in.firstjob = 0;
3287 0 : r.in.numjobs = 0xffffffff;
3288 0 : r.in.level = level;
3289 0 : r.in.buffer = NULL;
3290 0 : r.in.offered = 0;
3291 0 : r.out.needed = &needed;
3292 0 : r.out.count = &count;
3293 0 : r.out.info = &info;
3294 :
3295 0 : torture_comment(tctx, "Testing EnumJobs level %d\n", level);
3296 :
3297 0 : status = dcerpc_spoolss_EnumJobs_r(b, tctx, &r);
3298 :
3299 0 : torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
3300 :
3301 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
3302 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
3303 0 : r.in.buffer = &blob;
3304 0 : r.in.offered = needed;
3305 :
3306 0 : status = dcerpc_spoolss_EnumJobs_r(b, tctx, &r);
3307 :
3308 0 : torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
3309 0 : torture_assert_werr_equal(tctx, r.out.result, werr_expected,
3310 : "EnumJobs failed");
3311 0 : torture_assert(tctx, info, "No jobs returned");
3312 :
3313 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumJobs, *r.out.info, r.in.level, count, needed, 4);
3314 :
3315 : } else {
3316 0 : torture_assert_werr_equal(tctx, r.out.result, werr_expected,
3317 : "EnumJobs failed");
3318 : }
3319 :
3320 0 : if (count_p) {
3321 0 : *count_p = count;
3322 : }
3323 0 : if (info_p) {
3324 0 : *info_p = info;
3325 : }
3326 :
3327 0 : return true;
3328 : }
3329 :
3330 0 : static bool test_JobPropertiesEnum(struct torture_context *tctx,
3331 : struct dcerpc_binding_handle *b,
3332 : struct policy_handle *handle,
3333 : uint32_t job_id)
3334 : {
3335 : struct spoolss_EnumJobNamedProperties r;
3336 0 : uint32_t pcProperties = 0;
3337 0 : struct spoolss_PrintNamedProperty *ppProperties = NULL;
3338 :
3339 0 : r.in.hPrinter = handle;
3340 0 : r.in.JobId = job_id;
3341 0 : r.out.pcProperties = &pcProperties;
3342 0 : r.out.ppProperties = &ppProperties;
3343 :
3344 0 : torture_comment(tctx, "Testing EnumJobNamedProperties(%d)\n", job_id);
3345 :
3346 0 : torture_assert_ntstatus_ok(tctx,
3347 : dcerpc_spoolss_EnumJobNamedProperties_r(b, tctx, &r),
3348 : "spoolss_EnumJobNamedProperties failed");
3349 0 : torture_assert_werr_ok(tctx, r.out.result,
3350 : "spoolss_EnumJobNamedProperties failed");
3351 :
3352 0 : return true;
3353 : }
3354 :
3355 0 : static bool test_JobPropertySet(struct torture_context *tctx,
3356 : struct dcerpc_binding_handle *b,
3357 : struct policy_handle *handle,
3358 : uint32_t job_id,
3359 : struct spoolss_PrintNamedProperty *property)
3360 : {
3361 : struct spoolss_SetJobNamedProperty r;
3362 :
3363 0 : r.in.hPrinter = handle;
3364 0 : r.in.JobId = job_id;
3365 0 : r.in.pProperty = property;
3366 :
3367 0 : torture_comment(tctx, "Testing SetJobNamedProperty(%d) %s - %d\n",
3368 : job_id, property->propertyName,
3369 0 : property->propertyValue.ePropertyType);
3370 :
3371 0 : torture_assert_ntstatus_ok(tctx,
3372 : dcerpc_spoolss_SetJobNamedProperty_r(b, tctx, &r),
3373 : "spoolss_SetJobNamedProperty failed");
3374 0 : torture_assert_werr_ok(tctx, r.out.result,
3375 : "spoolss_SetJobNamedProperty failed");
3376 :
3377 0 : return true;
3378 : }
3379 :
3380 0 : static bool test_JobPropertyGetValue(struct torture_context *tctx,
3381 : struct dcerpc_binding_handle *b,
3382 : struct policy_handle *handle,
3383 : uint32_t job_id,
3384 : const char *property_name,
3385 : struct spoolss_PrintPropertyValue *value)
3386 : {
3387 : struct spoolss_GetJobNamedPropertyValue r;
3388 :
3389 0 : r.in.hPrinter = handle;
3390 0 : r.in.JobId = job_id;
3391 0 : r.in.pszName = property_name;
3392 0 : r.out.pValue = value;
3393 :
3394 0 : torture_comment(tctx, "Testing GetJobNamedPropertyValue(%d) %s\n",
3395 : job_id, property_name);
3396 :
3397 0 : torture_assert_ntstatus_ok(tctx,
3398 : dcerpc_spoolss_GetJobNamedPropertyValue_r(b, tctx, &r),
3399 : "spoolss_GetJobNamedPropertyValue failed");
3400 0 : torture_assert_werr_ok(tctx, r.out.result,
3401 : "spoolss_GetJobNamedPropertyValue failed");
3402 :
3403 0 : return true;
3404 : }
3405 :
3406 0 : static bool test_JobPropertyDelete(struct torture_context *tctx,
3407 : struct dcerpc_binding_handle *b,
3408 : struct policy_handle *handle,
3409 : uint32_t job_id,
3410 : const char *property_name)
3411 : {
3412 : struct spoolss_DeleteJobNamedProperty r;
3413 :
3414 0 : r.in.hPrinter = handle;
3415 0 : r.in.JobId = job_id;
3416 0 : r.in.pszName = property_name;
3417 :
3418 0 : torture_comment(tctx, "Testing DeleteJobNamedProperty(%d) %s\n",
3419 : job_id, property_name);
3420 :
3421 0 : torture_assert_ntstatus_ok(tctx,
3422 : dcerpc_spoolss_DeleteJobNamedProperty_r(b, tctx, &r),
3423 : "spoolss_DeleteJobNamedProperty failed");
3424 0 : torture_assert_werr_ok(tctx, r.out.result,
3425 : "spoolss_DeleteJobNamedProperty failed");
3426 :
3427 0 : return true;
3428 : }
3429 :
3430 0 : static bool test_DoPrintTest_add_one_job_common(struct torture_context *tctx,
3431 : struct dcerpc_binding_handle *b,
3432 : struct policy_handle *handle,
3433 : const char *document_name,
3434 : const char *datatype,
3435 : uint32_t *job_id)
3436 : {
3437 : NTSTATUS status;
3438 : struct spoolss_StartDocPrinter s;
3439 : struct spoolss_DocumentInfoCtr info_ctr;
3440 : struct spoolss_DocumentInfo1 info1;
3441 : struct spoolss_StartPagePrinter sp;
3442 : struct spoolss_WritePrinter w;
3443 : struct spoolss_EndPagePrinter ep;
3444 : struct spoolss_EndDocPrinter e;
3445 : int i;
3446 : uint32_t num_written;
3447 :
3448 0 : torture_comment(tctx, "Testing StartDocPrinter\n");
3449 :
3450 0 : s.in.handle = handle;
3451 0 : s.in.info_ctr = &info_ctr;
3452 0 : s.out.job_id = job_id;
3453 :
3454 0 : info1.document_name = document_name;
3455 0 : info1.output_file = NULL;
3456 0 : info1.datatype = datatype;
3457 :
3458 0 : info_ctr.level = 1;
3459 0 : info_ctr.info.info1 = &info1;
3460 :
3461 0 : status = dcerpc_spoolss_StartDocPrinter_r(b, tctx, &s);
3462 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_StartDocPrinter failed");
3463 0 : torture_assert_werr_ok(tctx, s.out.result, "StartDocPrinter failed");
3464 :
3465 0 : for (i=1; i < 4; i++) {
3466 : union spoolss_JobInfo ginfo;
3467 : bool ok;
3468 :
3469 0 : torture_comment(tctx, "Testing StartPagePrinter: Page[%d], JobId[%d]\n", i, *job_id);
3470 :
3471 0 : sp.in.handle = handle;
3472 :
3473 0 : status = dcerpc_spoolss_StartPagePrinter_r(b, tctx, &sp);
3474 0 : torture_assert_ntstatus_ok(tctx, status,
3475 : "dcerpc_spoolss_StartPagePrinter failed");
3476 0 : torture_assert_werr_ok(tctx, sp.out.result, "StartPagePrinter failed");
3477 :
3478 0 : ok = test_GetJob_args(tctx, b, handle, *job_id, 1, &ginfo);
3479 0 : if (!ok) {
3480 0 : torture_comment(tctx, "test_GetJob failed for JobId[%d]\n", *job_id);
3481 : }
3482 :
3483 0 : torture_comment(tctx, "Testing WritePrinter: Page[%d], JobId[%d]\n", i, *job_id);
3484 :
3485 0 : w.in.handle = handle;
3486 0 : w.in.data = data_blob_string_const(talloc_asprintf(tctx,"TortureTestPage: %d\nData\n",i));
3487 0 : w.out.num_written = &num_written;
3488 :
3489 0 : status = dcerpc_spoolss_WritePrinter_r(b, tctx, &w);
3490 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_WritePrinter failed");
3491 0 : torture_assert_werr_ok(tctx, w.out.result, "WritePrinter failed");
3492 :
3493 0 : torture_comment(tctx, "Testing EndPagePrinter: Page[%d], JobId[%d]\n", i, *job_id);
3494 :
3495 0 : ep.in.handle = handle;
3496 :
3497 0 : status = dcerpc_spoolss_EndPagePrinter_r(b, tctx, &ep);
3498 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndPagePrinter failed");
3499 0 : torture_assert_werr_ok(tctx, ep.out.result, "EndPagePrinter failed");
3500 : }
3501 :
3502 0 : torture_comment(tctx, "Testing EndDocPrinter: JobId[%d]\n", *job_id);
3503 :
3504 0 : e.in.handle = handle;
3505 :
3506 0 : status = dcerpc_spoolss_EndDocPrinter_r(b, tctx, &e);
3507 0 : torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndDocPrinter failed");
3508 0 : torture_assert_werr_ok(tctx, e.out.result, "EndDocPrinter failed");
3509 :
3510 0 : return true;
3511 : }
3512 :
3513 0 : static bool test_DoPrintTest_add_one_job(struct torture_context *tctx,
3514 : struct dcerpc_binding_handle *b,
3515 : struct policy_handle *handle,
3516 : const char *document_name,
3517 : uint32_t *job_id)
3518 : {
3519 0 : test_DoPrintTest_add_one_job_common(tctx, b, handle, document_name, "RAW", job_id);
3520 :
3521 0 : return true;
3522 : }
3523 :
3524 0 : static bool test_DoPrintTest_add_one_job_v4(struct torture_context *tctx,
3525 : struct dcerpc_binding_handle *b,
3526 : struct policy_handle *handle,
3527 : const char *document_name,
3528 : uint32_t *job_id)
3529 : {
3530 0 : test_DoPrintTest_add_one_job_common(tctx, b, handle, document_name, "XPS_PASS", job_id);
3531 :
3532 0 : return true;
3533 : }
3534 :
3535 :
3536 0 : static bool test_DoPrintTest_check_jobs(struct torture_context *tctx,
3537 : struct dcerpc_binding_handle *b,
3538 : struct policy_handle *handle,
3539 : uint32_t num_jobs,
3540 : uint32_t *job_ids)
3541 : {
3542 : uint32_t count;
3543 0 : union spoolss_JobInfo *info = NULL;
3544 : int i;
3545 :
3546 0 : torture_assert(tctx,
3547 : test_AddJob(tctx, b, handle),
3548 : "AddJob failed");
3549 :
3550 0 : torture_assert(tctx,
3551 : test_EnumJobs_args(tctx, b, handle, 1, WERR_OK, &count, &info),
3552 : "EnumJobs level 1 failed");
3553 :
3554 0 : torture_assert_int_equal(tctx, count, num_jobs, "unexpected number of jobs in queue");
3555 :
3556 0 : for (i=0; i < num_jobs; i++) {
3557 : union spoolss_JobInfo ginfo;
3558 : const char *document_name;
3559 0 : const char *new_document_name = "any_other_docname";
3560 : struct spoolss_JobInfoContainer ctr;
3561 : struct spoolss_SetJobInfo1 info1;
3562 :
3563 0 : torture_assert_int_equal(tctx, info[i].info1.job_id, job_ids[i], "job id mismatch");
3564 :
3565 0 : torture_assert(tctx,
3566 : test_GetJob_args(tctx, b, handle, info[i].info1.job_id, 1, &ginfo),
3567 : "failed to call test_GetJob");
3568 :
3569 0 : torture_assert_int_equal(tctx, ginfo.info1.job_id, info[i].info1.job_id, "job id mismatch");
3570 :
3571 0 : document_name = ginfo.info1.document_name;
3572 :
3573 0 : info1.job_id = ginfo.info1.job_id;
3574 0 : info1.printer_name = ginfo.info1.printer_name;
3575 0 : info1.server_name = ginfo.info1.server_name;
3576 0 : info1.user_name = ginfo.info1.user_name;
3577 0 : info1.document_name = new_document_name;
3578 0 : info1.data_type = ginfo.info1.data_type;
3579 0 : info1.text_status = ginfo.info1.text_status;
3580 0 : info1.status = ginfo.info1.status;
3581 0 : info1.priority = ginfo.info1.priority;
3582 0 : info1.position = ginfo.info1.position;
3583 0 : info1.total_pages = ginfo.info1.total_pages;
3584 0 : info1.pages_printed = ginfo.info1.pages_printed;
3585 0 : info1.submitted = ginfo.info1.submitted;
3586 :
3587 0 : ctr.level = 1;
3588 0 : ctr.info.info1 = &info1;
3589 :
3590 0 : torture_assert(tctx,
3591 : test_SetJob(tctx, b, handle, info[i].info1.job_id, &ctr, 0),
3592 : "failed to call test_SetJob level 1");
3593 :
3594 0 : torture_assert(tctx,
3595 : test_GetJob_args(tctx, b, handle, info[i].info1.job_id, 1, &ginfo),
3596 : "failed to call test_GetJob");
3597 :
3598 0 : if (strequal(ginfo.info1.document_name, document_name)) {
3599 0 : torture_warning(tctx,
3600 : "document_name did *NOT* change from '%s' to '%s'\n",
3601 : document_name, new_document_name);
3602 : }
3603 : }
3604 :
3605 0 : for (i=0; i < num_jobs; i++) {
3606 0 : if (!test_SetJob(tctx, b, handle, info[i].info1.job_id, NULL, SPOOLSS_JOB_CONTROL_PAUSE)) {
3607 0 : torture_warning(tctx, "failed to pause printjob\n");
3608 : }
3609 0 : if (!test_SetJob(tctx, b, handle, info[i].info1.job_id, NULL, SPOOLSS_JOB_CONTROL_RESUME)) {
3610 0 : torture_warning(tctx, "failed to resume printjob\n");
3611 : }
3612 : }
3613 :
3614 0 : return true;
3615 : }
3616 :
3617 0 : static bool test_DoPrintTest(struct torture_context *tctx,
3618 : struct dcerpc_binding_handle *b,
3619 : struct policy_handle *handle)
3620 : {
3621 0 : bool ret = true;
3622 0 : uint32_t num_jobs = 8;
3623 : uint32_t *job_ids;
3624 : int i;
3625 :
3626 0 : torture_comment(tctx, "Testing real print operations\n");
3627 :
3628 0 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
3629 :
3630 0 : for (i=0; i < num_jobs; i++) {
3631 0 : ret &= test_DoPrintTest_add_one_job(tctx, b, handle, "TorturePrintJob", &job_ids[i]);
3632 : }
3633 :
3634 0 : for (i=0; i < num_jobs; i++) {
3635 0 : ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
3636 : }
3637 :
3638 0 : for (i=0; i < num_jobs; i++) {
3639 0 : ret &= test_DoPrintTest_add_one_job_v4(tctx, b, handle, "TorturePrintJob v4", &job_ids[i]);
3640 : }
3641 :
3642 0 : for (i=0; i < num_jobs; i++) {
3643 0 : ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
3644 : }
3645 :
3646 0 : if (ret == true) {
3647 0 : torture_comment(tctx, "real print operations test succeeded\n\n");
3648 : }
3649 :
3650 0 : return ret;
3651 : }
3652 :
3653 0 : static bool test_DoPrintTest_extended(struct torture_context *tctx,
3654 : struct dcerpc_binding_handle *b,
3655 : struct policy_handle *handle)
3656 : {
3657 0 : bool ret = true;
3658 0 : uint32_t num_jobs = 8;
3659 : uint32_t *job_ids;
3660 : int i;
3661 0 : torture_comment(tctx, "Testing real print operations (extended)\n");
3662 :
3663 0 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
3664 :
3665 0 : for (i=0; i < num_jobs; i++) {
3666 0 : ret &= test_DoPrintTest_add_one_job(tctx, b, handle, "TorturePrintJob", &job_ids[i]);
3667 : }
3668 :
3669 0 : ret &= test_DoPrintTest_check_jobs(tctx, b, handle, num_jobs, job_ids);
3670 :
3671 0 : for (i=0; i < num_jobs; i++) {
3672 0 : ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
3673 : }
3674 :
3675 0 : if (ret == true) {
3676 0 : torture_comment(tctx, "real print operations (extended) test succeeded\n\n");
3677 : }
3678 :
3679 0 : return ret;
3680 : }
3681 :
3682 0 : static bool test_JobPrintProperties_equal(struct torture_context *tctx,
3683 : struct spoolss_PrintPropertyValue *got,
3684 : struct spoolss_PrintNamedProperty *exp)
3685 : {
3686 0 : torture_assert_int_equal(tctx,
3687 : got->ePropertyType,
3688 : exp->propertyValue.ePropertyType,
3689 : "ePropertyType");
3690 :
3691 0 : switch (exp->propertyValue.ePropertyType) {
3692 0 : case kRpcPropertyTypeString:
3693 0 : torture_assert_str_equal(tctx,
3694 : got->value.propertyString,
3695 : exp->propertyValue.value.propertyString,
3696 : "propertyString");
3697 0 : break;
3698 0 : case kRpcPropertyTypeInt32:
3699 0 : torture_assert_int_equal(tctx,
3700 : got->value.propertyInt32,
3701 : exp->propertyValue.value.propertyInt32,
3702 : "propertyInt32");
3703 0 : break;
3704 0 : case kRpcPropertyTypeInt64:
3705 0 : torture_assert_u64_equal(tctx,
3706 : got->value.propertyInt64,
3707 : exp->propertyValue.value.propertyInt64,
3708 : "propertyInt64");
3709 0 : break;
3710 0 : case kRpcPropertyTypeByte:
3711 0 : torture_assert_int_equal(tctx,
3712 : got->value.propertyByte,
3713 : exp->propertyValue.value.propertyByte,
3714 : "propertyByte");
3715 0 : break;
3716 0 : case kRpcPropertyTypeBuffer:
3717 0 : torture_assert_int_equal(tctx,
3718 : got->value.propertyBlob.cbBuf,
3719 : exp->propertyValue.value.propertyBlob.cbBuf,
3720 : "propertyBlob.cbBuf");
3721 0 : torture_assert_mem_equal(tctx,
3722 : got->value.propertyBlob.pBuf,
3723 : exp->propertyValue.value.propertyBlob.pBuf,
3724 : exp->propertyValue.value.propertyBlob.cbBuf,
3725 : "propertyBlob.pBuf");
3726 :
3727 0 : break;
3728 :
3729 : }
3730 :
3731 0 : return true;
3732 : }
3733 :
3734 0 : static bool test_JobPrintProperties(struct torture_context *tctx,
3735 : struct dcerpc_binding_handle *b,
3736 : struct policy_handle *handle,
3737 : uint32_t job_id)
3738 : {
3739 : struct spoolss_PrintNamedProperty in;
3740 : struct spoolss_PrintPropertyValue out;
3741 : int i;
3742 0 : DATA_BLOB blob = data_blob_string_const("blob");
3743 : struct {
3744 : const char *property_name;
3745 : enum spoolss_EPrintPropertyType type;
3746 : union spoolss_PrintPropertyValueUnion value;
3747 : WERROR expected_result;
3748 0 : } tests[] = {
3749 : {
3750 : .property_name = "torture_property_string",
3751 : .type = kRpcPropertyTypeString,
3752 : .value.propertyString = "torture_property_value_string",
3753 : },{
3754 : .property_name = "torture_property_int32",
3755 : .type = kRpcPropertyTypeInt32,
3756 : .value.propertyInt32 = 42,
3757 : },{
3758 : .property_name = "torture_property_int64",
3759 : .type = kRpcPropertyTypeInt64,
3760 : .value.propertyInt64 = 0xaffe,
3761 : },{
3762 : .property_name = "torture_property_byte",
3763 : .type = kRpcPropertyTypeByte,
3764 : .value.propertyByte = 0xab,
3765 : },{
3766 : .property_name = "torture_property_buffer",
3767 : .type = kRpcPropertyTypeBuffer,
3768 0 : .value.propertyBlob.cbBuf = blob.length,
3769 0 : .value.propertyBlob.pBuf = blob.data,
3770 : }
3771 : };
3772 :
3773 0 : torture_assert(tctx,
3774 : test_JobPropertiesEnum(tctx, b, handle, job_id),
3775 : "failed to enum properties");
3776 :
3777 0 : for (i=0; i <ARRAY_SIZE(tests); i++) {
3778 :
3779 0 : in.propertyName = tests[i].property_name;
3780 0 : in.propertyValue.ePropertyType = tests[i].type;
3781 0 : in.propertyValue.value = tests[i].value;
3782 :
3783 0 : torture_assert(tctx,
3784 : test_JobPropertySet(tctx, b, handle, job_id, &in),
3785 : "failed to set property");
3786 :
3787 0 : torture_assert(tctx,
3788 : test_JobPropertyGetValue(tctx, b, handle, job_id, in.propertyName, &out),
3789 : "failed to get property");
3790 :
3791 0 : torture_assert(tctx,
3792 : test_JobPrintProperties_equal(tctx, &out, &in),
3793 : "property unequal");
3794 :
3795 0 : torture_assert(tctx,
3796 : test_JobPropertiesEnum(tctx, b, handle, job_id),
3797 : "failed to enum properties");
3798 :
3799 0 : torture_assert(tctx,
3800 : test_JobPropertyDelete(tctx, b, handle, job_id, in.propertyName),
3801 : "failed to delete job property");
3802 : }
3803 :
3804 0 : torture_assert(tctx,
3805 : test_JobPropertiesEnum(tctx, b, handle, job_id),
3806 : "failed to enum properties");
3807 :
3808 0 : return true;
3809 : }
3810 :
3811 0 : static bool test_DoPrintTest_properties(struct torture_context *tctx,
3812 : struct dcerpc_binding_handle *b,
3813 : struct policy_handle *handle)
3814 : {
3815 0 : uint32_t num_jobs = 8;
3816 : uint32_t *job_ids;
3817 : int i;
3818 0 : torture_comment(tctx, "Testing real print operations (properties)\n");
3819 :
3820 0 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
3821 :
3822 0 : for (i=0; i < num_jobs; i++) {
3823 0 : torture_assert(tctx,
3824 : test_DoPrintTest_add_one_job(tctx, b, handle, "TorturePrintJob", &job_ids[i]),
3825 : "failed to create print job");
3826 : }
3827 :
3828 0 : for (i=0; i < num_jobs; i++) {
3829 0 : torture_assert(tctx,
3830 : test_JobPrintProperties(tctx, b, handle, job_ids[i]),
3831 : "failed to test job properties");
3832 : }
3833 :
3834 :
3835 0 : for (i=0; i < num_jobs; i++) {
3836 0 : torture_assert(tctx,
3837 : test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE),
3838 : "failed to delete printjob");
3839 : }
3840 :
3841 0 : torture_comment(tctx, "real print operations (properties) test succeeded\n\n");
3842 :
3843 0 : return true;
3844 : }
3845 :
3846 0 : static bool test_PausePrinter(struct torture_context *tctx,
3847 : struct dcerpc_binding_handle *b,
3848 : struct policy_handle *handle)
3849 : {
3850 : NTSTATUS status;
3851 : struct spoolss_SetPrinter r;
3852 : struct spoolss_SetPrinterInfoCtr info_ctr;
3853 : struct spoolss_DevmodeContainer devmode_ctr;
3854 : struct sec_desc_buf secdesc_ctr;
3855 :
3856 0 : info_ctr.level = 0;
3857 0 : info_ctr.info.info0 = NULL;
3858 :
3859 0 : ZERO_STRUCT(devmode_ctr);
3860 0 : ZERO_STRUCT(secdesc_ctr);
3861 :
3862 0 : r.in.handle = handle;
3863 0 : r.in.info_ctr = &info_ctr;
3864 0 : r.in.devmode_ctr = &devmode_ctr;
3865 0 : r.in.secdesc_ctr = &secdesc_ctr;
3866 0 : r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
3867 :
3868 0 : torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
3869 :
3870 0 : status = dcerpc_spoolss_SetPrinter_r(b, tctx, &r);
3871 :
3872 0 : torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
3873 :
3874 0 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
3875 :
3876 0 : return true;
3877 : }
3878 :
3879 0 : static bool test_ResumePrinter(struct torture_context *tctx,
3880 : struct dcerpc_binding_handle *b,
3881 : struct policy_handle *handle)
3882 : {
3883 : NTSTATUS status;
3884 : struct spoolss_SetPrinter r;
3885 : struct spoolss_SetPrinterInfoCtr info_ctr;
3886 : struct spoolss_DevmodeContainer devmode_ctr;
3887 : struct sec_desc_buf secdesc_ctr;
3888 :
3889 0 : info_ctr.level = 0;
3890 0 : info_ctr.info.info0 = NULL;
3891 :
3892 0 : ZERO_STRUCT(devmode_ctr);
3893 0 : ZERO_STRUCT(secdesc_ctr);
3894 :
3895 0 : r.in.handle = handle;
3896 0 : r.in.info_ctr = &info_ctr;
3897 0 : r.in.devmode_ctr = &devmode_ctr;
3898 0 : r.in.secdesc_ctr = &secdesc_ctr;
3899 0 : r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
3900 :
3901 0 : torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
3902 :
3903 0 : status = dcerpc_spoolss_SetPrinter_r(b, tctx, &r);
3904 :
3905 0 : torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
3906 :
3907 0 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
3908 :
3909 0 : return true;
3910 : }
3911 :
3912 0 : static bool test_printer_purge(struct torture_context *tctx,
3913 : struct dcerpc_binding_handle *b,
3914 : struct policy_handle *handle)
3915 : {
3916 : NTSTATUS status;
3917 : struct spoolss_SetPrinter r;
3918 : struct spoolss_SetPrinterInfoCtr info_ctr;
3919 : struct spoolss_DevmodeContainer devmode_ctr;
3920 : struct sec_desc_buf secdesc_ctr;
3921 :
3922 0 : info_ctr.level = 0;
3923 0 : info_ctr.info.info0 = NULL;
3924 :
3925 0 : ZERO_STRUCT(devmode_ctr);
3926 0 : ZERO_STRUCT(secdesc_ctr);
3927 :
3928 0 : r.in.handle = handle;
3929 0 : r.in.info_ctr = &info_ctr;
3930 0 : r.in.devmode_ctr = &devmode_ctr;
3931 0 : r.in.secdesc_ctr = &secdesc_ctr;
3932 0 : r.in.command = SPOOLSS_PRINTER_CONTROL_PURGE;
3933 :
3934 0 : torture_comment(tctx, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PURGE\n");
3935 :
3936 0 : status = dcerpc_spoolss_SetPrinter_r(b, tctx, &r);
3937 0 : torture_assert_ntstatus_ok(tctx, status, "SetPrinter failed");
3938 0 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
3939 :
3940 0 : return true;
3941 : }
3942 :
3943 0 : static bool test_GetPrinterData_checktype(struct torture_context *tctx,
3944 : struct dcerpc_binding_handle *b,
3945 : struct policy_handle *handle,
3946 : const char *value_name,
3947 : enum winreg_Type *expected_type,
3948 : enum winreg_Type *type_p,
3949 : uint8_t **data_p,
3950 : uint32_t *needed_p)
3951 : {
3952 : NTSTATUS status;
3953 : struct spoolss_GetPrinterData r;
3954 : uint32_t needed;
3955 : enum winreg_Type type;
3956 : union spoolss_PrinterData data;
3957 :
3958 0 : r.in.handle = handle;
3959 0 : r.in.value_name = value_name;
3960 0 : r.in.offered = 0;
3961 0 : r.out.needed = &needed;
3962 0 : r.out.type = &type;
3963 0 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
3964 :
3965 0 : torture_comment(tctx, "Testing GetPrinterData(%s)\n", r.in.value_name);
3966 :
3967 0 : status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &r);
3968 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
3969 :
3970 0 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
3971 0 : if (expected_type) {
3972 0 : torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
3973 : }
3974 0 : r.in.offered = needed;
3975 0 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
3976 0 : status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &r);
3977 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
3978 : }
3979 :
3980 0 : torture_assert_werr_ok(tctx, r.out.result,
3981 : talloc_asprintf(tctx, "GetPrinterData(%s) failed", r.in.value_name));
3982 :
3983 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, needed, 1);
3984 :
3985 0 : if (type_p) {
3986 0 : *type_p = type;
3987 : }
3988 :
3989 0 : if (data_p) {
3990 0 : *data_p = r.out.data;
3991 : }
3992 :
3993 0 : if (needed_p) {
3994 0 : *needed_p = needed;
3995 : }
3996 :
3997 0 : return true;
3998 : }
3999 :
4000 0 : static bool test_GetPrinterData(struct torture_context *tctx,
4001 : struct dcerpc_binding_handle *b,
4002 : struct policy_handle *handle,
4003 : const char *value_name,
4004 : enum winreg_Type *type_p,
4005 : uint8_t **data_p,
4006 : uint32_t *needed_p)
4007 : {
4008 0 : return test_GetPrinterData_checktype(tctx, b, handle, value_name,
4009 : NULL, type_p, data_p, needed_p);
4010 : }
4011 :
4012 0 : static bool test_GetPrinterDataEx_checktype(struct torture_context *tctx,
4013 : struct dcerpc_pipe *p,
4014 : struct policy_handle *handle,
4015 : const char *key_name,
4016 : const char *value_name,
4017 : enum winreg_Type *expected_type,
4018 : enum winreg_Type *type_p,
4019 : uint8_t **data_p,
4020 : uint32_t *needed_p)
4021 : {
4022 : NTSTATUS status;
4023 : struct spoolss_GetPrinterDataEx r;
4024 : enum winreg_Type type;
4025 : uint32_t needed;
4026 : union spoolss_PrinterData data;
4027 0 : struct dcerpc_binding_handle *b = p->binding_handle;
4028 :
4029 0 : r.in.handle = handle;
4030 0 : r.in.key_name = key_name;
4031 0 : r.in.value_name = value_name;
4032 0 : r.in.offered = 0;
4033 0 : r.out.type = &type;
4034 0 : r.out.needed = &needed;
4035 0 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
4036 :
4037 0 : torture_comment(tctx, "Testing GetPrinterDataEx(%s - %s)\n",
4038 : r.in.key_name, r.in.value_name);
4039 :
4040 0 : status = dcerpc_spoolss_GetPrinterDataEx_r(b, tctx, &r);
4041 0 : if (!NT_STATUS_IS_OK(status)) {
4042 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
4043 0 : torture_skip(tctx, "GetPrinterDataEx not supported by server\n");
4044 : }
4045 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
4046 : }
4047 :
4048 0 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
4049 0 : if (expected_type) {
4050 0 : torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
4051 : }
4052 0 : r.in.offered = needed;
4053 0 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
4054 0 : status = dcerpc_spoolss_GetPrinterDataEx_r(b, tctx, &r);
4055 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed");
4056 : }
4057 :
4058 0 : torture_assert_werr_ok(tctx, r.out.result,
4059 : talloc_asprintf(tctx, "GetPrinterDataEx(%s - %s) failed", r.in.key_name, r.in.value_name));
4060 :
4061 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, needed, 1);
4062 :
4063 0 : if (type_p) {
4064 0 : *type_p = type;
4065 : }
4066 :
4067 0 : if (data_p) {
4068 0 : *data_p = r.out.data;
4069 : }
4070 :
4071 0 : if (needed_p) {
4072 0 : *needed_p = needed;
4073 : }
4074 :
4075 0 : return true;
4076 : }
4077 :
4078 0 : static bool test_GetPrinterDataEx(struct torture_context *tctx,
4079 : struct dcerpc_pipe *p,
4080 : struct policy_handle *handle,
4081 : const char *key_name,
4082 : const char *value_name,
4083 : enum winreg_Type *type_p,
4084 : uint8_t **data_p,
4085 : uint32_t *needed_p)
4086 : {
4087 0 : return test_GetPrinterDataEx_checktype(tctx, p, handle, key_name, value_name,
4088 : NULL, type_p, data_p, needed_p);
4089 : }
4090 :
4091 0 : static bool test_get_environment(struct torture_context *tctx,
4092 : struct dcerpc_binding_handle *b,
4093 : struct policy_handle *handle,
4094 : const char **architecture)
4095 : {
4096 : DATA_BLOB blob;
4097 : enum winreg_Type type;
4098 : uint8_t *data;
4099 : uint32_t needed;
4100 :
4101 0 : torture_assert(tctx,
4102 : test_GetPrinterData(tctx, b, handle, "Architecture", &type, &data, &needed),
4103 : "failed to get Architecture");
4104 :
4105 0 : torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");
4106 :
4107 0 : blob = data_blob_const(data, needed);
4108 0 : *architecture = reg_val_data_string(tctx, REG_SZ, blob);
4109 :
4110 0 : return true;
4111 : }
4112 :
4113 0 : static bool test_GetPrinterData_list(struct torture_context *tctx,
4114 : void *private_data)
4115 : {
4116 0 : struct test_spoolss_context *ctx =
4117 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
4118 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
4119 0 : struct dcerpc_binding_handle *b = p->binding_handle;
4120 0 : const char *list[] = {
4121 : "W3SvcInstalled",
4122 : "BeepEnabled",
4123 : "EventLog",
4124 : /* "NetPopup", not on w2k8 */
4125 : /* "NetPopupToComputer", not on w2k8 */
4126 : "MajorVersion",
4127 : "MinorVersion",
4128 : "DefaultSpoolDirectory",
4129 : "Architecture",
4130 : "DsPresent",
4131 : "OSVersion",
4132 : /* "OSVersionEx", not on s3 */
4133 : "DNSMachineName"
4134 : };
4135 : int i;
4136 :
4137 0 : for (i=0; i < ARRAY_SIZE(list); i++) {
4138 0 : enum winreg_Type type = REG_NONE;
4139 0 : enum winreg_Type type_ex1 = REG_NONE;
4140 0 : enum winreg_Type type_ex2 = REG_NONE;
4141 : uint8_t *data;
4142 0 : uint8_t *data_ex1 = NULL;
4143 0 : uint8_t *data_ex2 = NULL;
4144 : uint32_t needed;
4145 0 : uint32_t needed_ex1 = 0;
4146 0 : uint32_t needed_ex2 = 0;
4147 :
4148 0 : torture_assert(tctx, test_GetPrinterData(tctx, b, &ctx->server_handle, list[i], &type, &data, &needed),
4149 : talloc_asprintf(tctx, "GetPrinterData failed on %s\n", list[i]));
4150 0 : torture_assert(tctx, test_GetPrinterDataEx(tctx, p, &ctx->server_handle, "random_string", list[i], &type_ex1, &data_ex1, &needed_ex1),
4151 : talloc_asprintf(tctx, "GetPrinterDataEx failed on %s\n", list[i]));
4152 0 : torture_assert(tctx, test_GetPrinterDataEx(tctx, p, &ctx->server_handle, "", list[i], &type_ex2, &data_ex2, &needed_ex2),
4153 : talloc_asprintf(tctx, "GetPrinterDataEx failed on %s\n", list[i]));
4154 0 : torture_assert_int_equal(tctx, type, type_ex1, "type mismatch");
4155 0 : torture_assert_int_equal(tctx, type, type_ex2, "type mismatch");
4156 0 : torture_assert_int_equal(tctx, needed, needed_ex1, "needed mismatch");
4157 0 : torture_assert_int_equal(tctx, needed, needed_ex2, "needed mismatch");
4158 0 : torture_assert_mem_equal(tctx, data, data_ex1, needed, "data mismatch");
4159 0 : torture_assert_mem_equal(tctx, data, data_ex2, needed, "data mismatch");
4160 : }
4161 :
4162 0 : return true;
4163 : }
4164 :
4165 0 : static bool test_EnumPrinterData(struct torture_context *tctx,
4166 : struct dcerpc_pipe *p,
4167 : struct policy_handle *handle,
4168 : uint32_t enum_index,
4169 : uint32_t value_offered,
4170 : uint32_t data_offered,
4171 : enum winreg_Type *type_p,
4172 : uint32_t *value_needed_p,
4173 : uint32_t *data_needed_p,
4174 : const char **value_name_p,
4175 : uint8_t **data_p,
4176 : WERROR *result_p)
4177 : {
4178 : struct spoolss_EnumPrinterData r;
4179 : uint32_t data_needed;
4180 : uint32_t value_needed;
4181 : enum winreg_Type type;
4182 0 : struct dcerpc_binding_handle *b = p->binding_handle;
4183 :
4184 0 : r.in.handle = handle;
4185 0 : r.in.enum_index = enum_index;
4186 0 : r.in.value_offered = value_offered;
4187 0 : r.in.data_offered = data_offered;
4188 0 : r.out.data_needed = &data_needed;
4189 0 : r.out.value_needed = &value_needed;
4190 0 : r.out.type = &type;
4191 0 : r.out.data = talloc_zero_array(tctx, uint8_t, r.in.data_offered);
4192 0 : r.out.value_name = talloc_zero_array(tctx, const char, r.in.value_offered);
4193 :
4194 0 : torture_comment(tctx, "Testing EnumPrinterData(%d)\n", enum_index);
4195 :
4196 0 : torture_assert_ntstatus_ok(tctx,
4197 : dcerpc_spoolss_EnumPrinterData_r(b, tctx, &r),
4198 : "EnumPrinterData failed");
4199 :
4200 0 : if (type_p) {
4201 0 : *type_p = type;
4202 : }
4203 0 : if (value_needed_p) {
4204 0 : *value_needed_p = value_needed;
4205 : }
4206 0 : if (data_needed_p) {
4207 0 : *data_needed_p = data_needed;
4208 : }
4209 0 : if (value_name_p) {
4210 0 : *value_name_p = r.out.value_name;
4211 : }
4212 0 : if (data_p) {
4213 0 : *data_p = r.out.data;
4214 : }
4215 0 : if (result_p) {
4216 0 : *result_p = r.out.result;
4217 : }
4218 :
4219 0 : return true;
4220 : }
4221 :
4222 :
4223 0 : static bool test_EnumPrinterData_all(struct torture_context *tctx,
4224 : struct dcerpc_pipe *p,
4225 : struct policy_handle *handle)
4226 : {
4227 0 : uint32_t enum_index = 0;
4228 : enum winreg_Type type;
4229 : uint32_t value_needed;
4230 : uint32_t data_needed;
4231 : uint8_t *data;
4232 : const char *value_name;
4233 : WERROR result;
4234 :
4235 0 : torture_comment(tctx, "Testing EnumPrinterData\n");
4236 :
4237 : do {
4238 0 : torture_assert(tctx,
4239 : test_EnumPrinterData(tctx, p, handle, enum_index, 0, 0,
4240 : &type, &value_needed, &data_needed,
4241 : &value_name, &data, &result),
4242 : "EnumPrinterData failed");
4243 :
4244 0 : if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS)) {
4245 0 : break;
4246 : }
4247 :
4248 0 : torture_assert(tctx,
4249 : test_EnumPrinterData(tctx, p, handle, enum_index, value_needed, data_needed,
4250 : &type, &value_needed, &data_needed,
4251 : &value_name, &data, &result),
4252 : "EnumPrinterData failed");
4253 :
4254 0 : if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS)) {
4255 0 : break;
4256 : }
4257 :
4258 0 : enum_index++;
4259 :
4260 0 : } while (W_ERROR_IS_OK(result));
4261 :
4262 0 : torture_comment(tctx, "EnumPrinterData test succeeded\n");
4263 :
4264 0 : return true;
4265 : }
4266 :
4267 0 : static bool test_EnumPrinterDataEx(struct torture_context *tctx,
4268 : struct dcerpc_binding_handle *b,
4269 : struct policy_handle *handle,
4270 : const char *key_name,
4271 : uint32_t *count_p,
4272 : struct spoolss_PrinterEnumValues **info_p)
4273 : {
4274 : struct spoolss_EnumPrinterDataEx r;
4275 : struct spoolss_PrinterEnumValues *info;
4276 : uint32_t needed;
4277 : uint32_t count;
4278 :
4279 0 : r.in.handle = handle;
4280 0 : r.in.key_name = key_name;
4281 0 : r.in.offered = 0;
4282 0 : r.out.needed = &needed;
4283 0 : r.out.count = &count;
4284 0 : r.out.info = &info;
4285 :
4286 0 : torture_comment(tctx, "Testing EnumPrinterDataEx(%s)\n", key_name);
4287 :
4288 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &r),
4289 : "EnumPrinterDataEx failed");
4290 0 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
4291 0 : r.in.offered = needed;
4292 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &r),
4293 : "EnumPrinterDataEx failed");
4294 : }
4295 :
4296 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDataEx failed");
4297 :
4298 0 : CHECK_NEEDED_SIZE_ENUM(spoolss_EnumPrinterDataEx, info, count, needed, 1);
4299 :
4300 0 : if (count_p) {
4301 0 : *count_p = count;
4302 : }
4303 0 : if (info_p) {
4304 0 : *info_p = info;
4305 : }
4306 :
4307 0 : return true;
4308 : }
4309 :
4310 : static bool test_SetPrinterData(struct torture_context *tctx,
4311 : struct dcerpc_binding_handle *b,
4312 : struct policy_handle *handle,
4313 : const char *value_name,
4314 : enum winreg_Type type,
4315 : uint8_t *data,
4316 : uint32_t offered);
4317 : static bool test_DeletePrinterData(struct torture_context *tctx,
4318 : struct dcerpc_binding_handle *b,
4319 : struct policy_handle *handle,
4320 : const char *value_name);
4321 :
4322 0 : static bool test_EnumPrinterData_consistency(struct torture_context *tctx,
4323 : struct dcerpc_pipe *p,
4324 : struct policy_handle *handle)
4325 : {
4326 : uint32_t count;
4327 : struct spoolss_PrinterEnumValues *info;
4328 : int i;
4329 : uint32_t value_needed, data_needed;
4330 : uint32_t value_offered, data_offered;
4331 : WERROR result;
4332 0 : struct dcerpc_binding_handle *b = p->binding_handle;
4333 :
4334 : enum winreg_Type type;
4335 : DATA_BLOB blob;
4336 :
4337 0 : torture_comment(tctx, "Testing EnumPrinterData vs EnumPrinterDataEx consistency\n");
4338 :
4339 0 : torture_assert(tctx, push_reg_sz(tctx, &blob, "torture_data1"), "");
4340 0 : type = REG_SZ;
4341 :
4342 0 : torture_assert(tctx,
4343 : test_SetPrinterData(tctx, b, handle, "torture_value1", type, blob.data, blob.length),
4344 : "SetPrinterData failed");
4345 :
4346 0 : blob = data_blob_string_const("torture_data2");
4347 :
4348 0 : torture_assert(tctx,
4349 : test_SetPrinterData(tctx, b, handle, "torture_value2", REG_BINARY, blob.data, blob.length),
4350 : "SetPrinterData failed");
4351 :
4352 0 : blob = data_blob_talloc(tctx, NULL, 4);
4353 0 : SIVAL(blob.data, 0, 0x11223344);
4354 :
4355 0 : torture_assert(tctx,
4356 : test_SetPrinterData(tctx, b, handle, "torture_value3", type, blob.data, blob.length),
4357 : "SetPrinterData failed");
4358 :
4359 0 : torture_assert(tctx,
4360 : test_EnumPrinterDataEx(tctx, b, handle, "PrinterDriverData", &count, &info),
4361 : "failed to call EnumPrinterDataEx");
4362 :
4363 : /* get the max sizes for value and data */
4364 :
4365 0 : torture_assert(tctx,
4366 : test_EnumPrinterData(tctx, p, handle, 0, 0, 0,
4367 : NULL, &value_needed, &data_needed,
4368 : NULL, NULL, &result),
4369 : "EnumPrinterData failed");
4370 0 : torture_assert_werr_ok(tctx, result, "unexpected result");
4371 :
4372 : /* check if the reply from the EnumPrinterData really matches max values */
4373 :
4374 0 : for (i=0; i < count; i++) {
4375 0 : if (info[i].value_name_len > value_needed) {
4376 0 : torture_fail(tctx,
4377 : talloc_asprintf(tctx,
4378 : "EnumPrinterDataEx gave a reply with value length %d which is larger then expected max value length %d from EnumPrinterData",
4379 : info[i].value_name_len, value_needed));
4380 : }
4381 0 : if (info[i].data_length > data_needed) {
4382 0 : torture_fail(tctx,
4383 : talloc_asprintf(tctx,
4384 : "EnumPrinterDataEx gave a reply with data length %d which is larger then expected max data length %d from EnumPrinterData",
4385 : info[i].data_length, data_needed));
4386 : }
4387 : }
4388 :
4389 : /* assuming that both EnumPrinterData and EnumPrinterDataEx do either
4390 : * sort or not sort the replies by value name, we should be able to do
4391 : * the following entry comparison */
4392 :
4393 0 : data_offered = data_needed;
4394 0 : value_offered = value_needed;
4395 :
4396 0 : for (i=0; i < count; i++) {
4397 :
4398 : const char *value_name;
4399 : uint8_t *data;
4400 :
4401 0 : torture_assert(tctx,
4402 : test_EnumPrinterData(tctx, p, handle, i, value_offered, data_offered,
4403 : &type, &value_needed, &data_needed,
4404 : &value_name, &data, &result),
4405 : "EnumPrinterData failed");
4406 :
4407 0 : if (i -1 == count) {
4408 0 : torture_assert_werr_equal(tctx, result, WERR_NO_MORE_ITEMS,
4409 : "unexpected result");
4410 0 : break;
4411 : } else {
4412 0 : torture_assert_werr_ok(tctx, result, "unexpected result");
4413 : }
4414 :
4415 0 : torture_assert_int_equal(tctx, type, info[i].type, "type mismatch");
4416 0 : torture_assert_int_equal(tctx, value_needed, info[i].value_name_len, "value name length mismatch");
4417 0 : torture_assert_str_equal(tctx, value_name, info[i].value_name, "value name mismatch");
4418 0 : torture_assert_int_equal(tctx, data_needed, info[i].data_length, "data length mismatch");
4419 0 : torture_assert_mem_equal(tctx, data, info[i].data->data, info[i].data_length, "data mismatch");
4420 : }
4421 :
4422 0 : torture_assert(tctx,
4423 : test_DeletePrinterData(tctx, b, handle, "torture_value1"),
4424 : "DeletePrinterData failed");
4425 0 : torture_assert(tctx,
4426 : test_DeletePrinterData(tctx, b, handle, "torture_value2"),
4427 : "DeletePrinterData failed");
4428 0 : torture_assert(tctx,
4429 : test_DeletePrinterData(tctx, b, handle, "torture_value3"),
4430 : "DeletePrinterData failed");
4431 :
4432 0 : torture_comment(tctx, "EnumPrinterData vs EnumPrinterDataEx consistency test succeeded\n\n");
4433 :
4434 0 : return true;
4435 : }
4436 :
4437 0 : static bool test_DeletePrinterData(struct torture_context *tctx,
4438 : struct dcerpc_binding_handle *b,
4439 : struct policy_handle *handle,
4440 : const char *value_name)
4441 : {
4442 : NTSTATUS status;
4443 : struct spoolss_DeletePrinterData r;
4444 :
4445 0 : r.in.handle = handle;
4446 0 : r.in.value_name = value_name;
4447 :
4448 0 : torture_comment(tctx, "Testing DeletePrinterData(%s)\n",
4449 : r.in.value_name);
4450 :
4451 0 : status = dcerpc_spoolss_DeletePrinterData_r(b, tctx, &r);
4452 :
4453 0 : torture_assert_ntstatus_ok(tctx, status, "DeletePrinterData failed");
4454 0 : torture_assert_werr_ok(tctx, r.out.result, "DeletePrinterData failed");
4455 :
4456 0 : return true;
4457 : }
4458 :
4459 0 : static bool test_DeletePrinterDataEx(struct torture_context *tctx,
4460 : struct dcerpc_binding_handle *b,
4461 : struct policy_handle *handle,
4462 : const char *key_name,
4463 : const char *value_name)
4464 : {
4465 : struct spoolss_DeletePrinterDataEx r;
4466 :
4467 0 : r.in.handle = handle;
4468 0 : r.in.key_name = key_name;
4469 0 : r.in.value_name = value_name;
4470 :
4471 0 : torture_comment(tctx, "Testing DeletePrinterDataEx(%s - %s)\n",
4472 : r.in.key_name, r.in.value_name);
4473 :
4474 0 : torture_assert_ntstatus_ok(tctx,
4475 : dcerpc_spoolss_DeletePrinterDataEx_r(b, tctx, &r),
4476 : "DeletePrinterDataEx failed");
4477 0 : torture_assert_werr_ok(tctx, r.out.result,
4478 : "DeletePrinterDataEx failed");
4479 :
4480 0 : return true;
4481 : }
4482 :
4483 0 : static bool test_DeletePrinterKey(struct torture_context *tctx,
4484 : struct dcerpc_binding_handle *b,
4485 : struct policy_handle *handle,
4486 : const char *key_name)
4487 : {
4488 : struct spoolss_DeletePrinterKey r;
4489 :
4490 0 : r.in.handle = handle;
4491 0 : r.in.key_name = key_name;
4492 :
4493 0 : torture_comment(tctx, "Testing DeletePrinterKey(%s)\n", r.in.key_name);
4494 :
4495 0 : if (strequal(key_name, "") && !torture_setting_bool(tctx, "dangerous", false)) {
4496 0 : torture_skip(tctx, "not wiping out printer registry - enable dangerous tests to use\n");
4497 : return true;
4498 : }
4499 :
4500 0 : torture_assert_ntstatus_ok(tctx,
4501 : dcerpc_spoolss_DeletePrinterKey_r(b, tctx, &r),
4502 : "DeletePrinterKey failed");
4503 0 : torture_assert_werr_ok(tctx, r.out.result,
4504 : "DeletePrinterKey failed");
4505 :
4506 0 : return true;
4507 : }
4508 :
4509 0 : static bool test_winreg_OpenHKLM(struct torture_context *tctx,
4510 : struct dcerpc_binding_handle *b,
4511 : struct policy_handle *handle)
4512 : {
4513 : struct winreg_OpenHKLM r;
4514 :
4515 0 : r.in.system_name = NULL;
4516 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4517 0 : r.out.handle = handle;
4518 :
4519 0 : torture_comment(tctx, "Testing winreg_OpenHKLM\n");
4520 :
4521 0 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenHKLM_r(b, tctx, &r), "OpenHKLM failed");
4522 0 : torture_assert_werr_ok(tctx, r.out.result, "OpenHKLM failed");
4523 :
4524 0 : return true;
4525 : }
4526 :
4527 1494 : static void init_winreg_String(struct winreg_String *name, const char *s)
4528 : {
4529 1494 : name->name = s;
4530 1494 : if (s) {
4531 1494 : name->name_len = 2 * (strlen_m(s) + 1);
4532 1494 : name->name_size = name->name_len;
4533 : } else {
4534 0 : name->name_len = 0;
4535 0 : name->name_size = 0;
4536 : }
4537 1494 : }
4538 :
4539 0 : static bool test_winreg_OpenKey_opts(struct torture_context *tctx,
4540 : struct dcerpc_binding_handle *b,
4541 : struct policy_handle *hive_handle,
4542 : const char *keyname,
4543 : uint32_t options,
4544 : struct policy_handle *key_handle)
4545 : {
4546 : struct winreg_OpenKey r;
4547 :
4548 0 : r.in.parent_handle = hive_handle;
4549 0 : init_winreg_String(&r.in.keyname, keyname);
4550 0 : r.in.options = options;
4551 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4552 0 : r.out.handle = key_handle;
4553 :
4554 0 : torture_comment(tctx, "Testing winreg_OpenKey(%s)\n", keyname);
4555 :
4556 0 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r), "OpenKey failed");
4557 0 : torture_assert_werr_ok(tctx, r.out.result, "OpenKey failed");
4558 :
4559 0 : return true;
4560 : }
4561 :
4562 0 : static bool test_winreg_OpenKey(struct torture_context *tctx,
4563 : struct dcerpc_binding_handle *b,
4564 : struct policy_handle *hive_handle,
4565 : const char *keyname,
4566 : struct policy_handle *key_handle)
4567 : {
4568 0 : return test_winreg_OpenKey_opts(tctx, b, hive_handle, keyname,
4569 : REG_OPTION_NON_VOLATILE, key_handle);
4570 : }
4571 :
4572 0 : static bool test_winreg_CloseKey(struct torture_context *tctx,
4573 : struct dcerpc_binding_handle *b,
4574 : struct policy_handle *handle)
4575 : {
4576 : struct winreg_CloseKey r;
4577 :
4578 0 : r.in.handle = handle;
4579 0 : r.out.handle = handle;
4580 :
4581 0 : torture_comment(tctx, "Testing winreg_CloseKey\n");
4582 :
4583 0 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r), "CloseKey failed");
4584 0 : torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
4585 :
4586 0 : return true;
4587 : }
4588 :
4589 1494 : bool test_winreg_QueryValue(struct torture_context *tctx,
4590 : struct dcerpc_binding_handle *b,
4591 : struct policy_handle *handle,
4592 : const char *value_name,
4593 : enum winreg_Type *type_p,
4594 : uint32_t *data_size_p,
4595 : uint32_t *data_length_p,
4596 : uint8_t **data_p)
4597 : {
4598 : struct winreg_QueryValue r;
4599 1494 : enum winreg_Type type = REG_NONE;
4600 1494 : uint32_t data_size = 0;
4601 1494 : uint32_t data_length = 0;
4602 : struct winreg_String valuename;
4603 1494 : uint8_t *data = NULL;
4604 :
4605 1494 : init_winreg_String(&valuename, value_name);
4606 :
4607 1494 : data = talloc_zero_array(tctx, uint8_t, 0);
4608 :
4609 1494 : r.in.handle = handle;
4610 1494 : r.in.value_name = &valuename;
4611 1494 : r.in.type = &type;
4612 1494 : r.in.data_size = &data_size;
4613 1494 : r.in.data_length = &data_length;
4614 1494 : r.in.data = data;
4615 1494 : r.out.type = &type;
4616 1494 : r.out.data = data;
4617 1494 : r.out.data_size = &data_size;
4618 1494 : r.out.data_length = &data_length;
4619 :
4620 1494 : torture_comment(tctx, "Testing winreg_QueryValue(%s)\n", value_name);
4621 :
4622 1494 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
4623 1494 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
4624 1494 : *r.in.data_size = *r.out.data_size;
4625 1494 : data = talloc_zero_array(tctx, uint8_t, *r.in.data_size);
4626 1494 : r.in.data = data;
4627 1494 : r.out.data = data;
4628 1494 : torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
4629 : }
4630 1494 : torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
4631 :
4632 1494 : if (type_p) {
4633 1494 : *type_p = *r.out.type;
4634 : }
4635 1494 : if (data_size_p) {
4636 1494 : *data_size_p = *r.out.data_size;
4637 : }
4638 1494 : if (data_length_p) {
4639 1494 : *data_length_p = *r.out.data_length;
4640 : }
4641 1494 : if (data_p) {
4642 1494 : *data_p = r.out.data;
4643 : }
4644 :
4645 1494 : return true;
4646 : }
4647 :
4648 0 : static bool test_winreg_query_printerdata(struct torture_context *tctx,
4649 : struct dcerpc_binding_handle *b,
4650 : struct policy_handle *handle,
4651 : const char *printer_name,
4652 : const char *key_name,
4653 : const char *value_name,
4654 : enum winreg_Type *w_type,
4655 : uint32_t *w_size,
4656 : uint32_t *w_length,
4657 : uint8_t **w_data)
4658 : {
4659 : const char *printer_key;
4660 : struct policy_handle key_handle;
4661 :
4662 0 : printer_key = talloc_asprintf(tctx, "%s\\%s\\%s",
4663 : TOP_LEVEL_PRINT_PRINTERS_KEY, printer_name, key_name);
4664 :
4665 0 : torture_assert(tctx,
4666 : test_winreg_OpenKey(tctx, b, handle, printer_key, &key_handle), "");
4667 :
4668 0 : torture_assert(tctx,
4669 : test_winreg_QueryValue(tctx, b, &key_handle, value_name, w_type, w_size, w_length, w_data), "");
4670 :
4671 0 : torture_assert(tctx,
4672 : test_winreg_CloseKey(tctx, b, &key_handle), "");
4673 :
4674 0 : return true;
4675 : }
4676 :
4677 0 : static bool test_GetForm_winreg(struct torture_context *tctx,
4678 : struct dcerpc_binding_handle *b,
4679 : struct policy_handle *handle,
4680 : const char *key_name,
4681 : const char *form_name,
4682 : enum winreg_Type *w_type,
4683 : uint32_t *w_size,
4684 : uint32_t *w_length,
4685 : uint8_t **w_data)
4686 : {
4687 : struct policy_handle key_handle;
4688 :
4689 0 : torture_assert(tctx,
4690 : test_winreg_OpenKey(tctx, b, handle, key_name, &key_handle), "");
4691 :
4692 0 : torture_assert(tctx,
4693 : test_winreg_QueryValue(tctx, b, &key_handle, form_name, w_type, w_size, w_length, w_data), "");
4694 :
4695 0 : torture_assert(tctx,
4696 : test_winreg_CloseKey(tctx, b, &key_handle), "");
4697 :
4698 0 : return true;
4699 : }
4700 :
4701 0 : static bool test_winreg_symbolic_link(struct torture_context *tctx,
4702 : struct dcerpc_binding_handle *b,
4703 : struct policy_handle *handle,
4704 : const char *symlink_keyname,
4705 : const char *symlink_destination)
4706 : {
4707 : /* check if the first key is a symlink to the second key */
4708 :
4709 : enum winreg_Type w_type;
4710 : uint32_t w_size;
4711 : uint32_t w_length;
4712 : uint8_t *w_data;
4713 : struct policy_handle key_handle;
4714 : DATA_BLOB blob;
4715 : const char *str;
4716 :
4717 0 : if (torture_setting_bool(tctx, "samba3", false)) {
4718 0 : torture_skip(tctx, "skip winreg symlink test against samba");
4719 : }
4720 :
4721 0 : torture_assert(tctx,
4722 : test_winreg_OpenKey_opts(tctx, b, handle, symlink_keyname, REG_OPTION_OPEN_LINK, &key_handle),
4723 : "failed to open key link");
4724 :
4725 0 : torture_assert(tctx,
4726 : test_winreg_QueryValue(tctx, b, &key_handle,
4727 : "SymbolicLinkValue",
4728 : &w_type, &w_size, &w_length, &w_data),
4729 : "failed to query for 'SymbolicLinkValue' attribute");
4730 :
4731 0 : torture_assert_int_equal(tctx, w_type, REG_LINK, "unexpected type");
4732 :
4733 0 : blob = data_blob(w_data, w_size);
4734 0 : str = reg_val_data_string(tctx, REG_SZ, blob);
4735 :
4736 0 : torture_assert_str_equal(tctx, str, symlink_destination, "unexpected symlink target string");
4737 :
4738 0 : torture_assert(tctx,
4739 : test_winreg_CloseKey(tctx, b, &key_handle),
4740 : "failed to close key link");
4741 :
4742 0 : return true;
4743 : }
4744 :
4745 0 : static const char *strip_unc(const char *unc)
4746 : {
4747 : char *name;
4748 :
4749 0 : if (!unc) {
4750 0 : return NULL;
4751 : }
4752 :
4753 0 : if (unc[0] == '\\' && unc[1] == '\\') {
4754 0 : unc +=2;
4755 : }
4756 :
4757 0 : name = strchr(unc, '\\');
4758 0 : if (name) {
4759 0 : return name+1;
4760 : }
4761 :
4762 0 : return unc;
4763 : }
4764 :
4765 0 : static bool test_GetPrinterInfo_winreg(struct torture_context *tctx,
4766 : struct dcerpc_binding_handle *b,
4767 : struct policy_handle *handle,
4768 : const char *printer_name,
4769 : struct dcerpc_binding_handle *winreg_handle,
4770 : struct policy_handle *hive_handle)
4771 : {
4772 : union spoolss_PrinterInfo info;
4773 0 : const char *keys[] = {
4774 : TOP_LEVEL_CONTROL_PRINTERS_KEY,
4775 : TOP_LEVEL_PRINT_PRINTERS_KEY
4776 : };
4777 : int i;
4778 : const char *printername, *sharename;
4779 :
4780 0 : torture_comment(tctx, "Testing Printer Info and winreg consistency\n");
4781 :
4782 0 : torture_assert(tctx,
4783 : test_GetPrinter_level(tctx, b, handle, 2, &info),
4784 : "failed to get printer info level 2");
4785 :
4786 0 : printername = strip_unc(info.info2.printername);
4787 0 : sharename = strip_unc(info.info2.sharename);
4788 :
4789 : #define test_sz(wname, iname) \
4790 : do {\
4791 : DATA_BLOB blob;\
4792 : const char *str;\
4793 : enum winreg_Type w_type;\
4794 : uint32_t w_size;\
4795 : uint32_t w_length;\
4796 : uint8_t *w_data;\
4797 : torture_assert(tctx,\
4798 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4799 : &w_type, &w_size, &w_length, &w_data),\
4800 : "failed to query winreg");\
4801 : torture_assert_int_equal(tctx, w_type, REG_SZ, "unexpected type");\
4802 : blob = data_blob(w_data, w_size);\
4803 : str = reg_val_data_string(tctx, REG_SZ, blob);\
4804 : if (w_size == 2 && iname == NULL) {\
4805 : /*torture_comment(tctx, "%s: \"\", %s: (null)\n", #wname, #iname);\ */\
4806 : } else {\
4807 : torture_assert_str_equal(tctx, str, iname,\
4808 : talloc_asprintf(tctx, "%s - %s mismatch", #wname, #iname));\
4809 : }\
4810 : } while(0);
4811 :
4812 : #define test_dword(wname, iname) \
4813 : do {\
4814 : uint32_t value;\
4815 : enum winreg_Type w_type;\
4816 : uint32_t w_size;\
4817 : uint32_t w_length;\
4818 : uint8_t *w_data;\
4819 : torture_assert(tctx,\
4820 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4821 : &w_type, &w_size, &w_length, &w_data),\
4822 : "failed to query winreg");\
4823 : torture_assert_int_equal(tctx, w_type, REG_DWORD, "unexpected type");\
4824 : torture_assert_int_equal(tctx, w_size, 4, "unexpected size");\
4825 : torture_assert_int_equal(tctx, w_length, 4, "unexpected length");\
4826 : value = IVAL(w_data, 0);\
4827 : torture_assert_int_equal(tctx, value, iname,\
4828 : talloc_asprintf(tctx, "%s - %s mismatch", #wname, #iname));\
4829 : } while(0);
4830 :
4831 : #define test_binary(wname, iname) \
4832 : do {\
4833 : enum winreg_Type w_type;\
4834 : uint32_t w_size;\
4835 : uint32_t w_length;\
4836 : uint8_t *w_data;\
4837 : torture_assert(tctx,\
4838 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4839 : &w_type, &w_size, &w_length, &w_data),\
4840 : "failed to query winreg");\
4841 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4842 : torture_assert_int_equal(tctx, w_size, iname.length, "unexpected length");\
4843 : torture_assert_mem_equal(tctx, w_data, iname.data, w_size, \
4844 : "binary unequal");\
4845 : } while(0);
4846 :
4847 :
4848 : #define test_dm(wname, iname) \
4849 : do {\
4850 : DATA_BLOB blob;\
4851 : struct spoolss_DeviceMode dm;\
4852 : enum ndr_err_code ndr_err;\
4853 : enum winreg_Type w_type;\
4854 : uint32_t w_size;\
4855 : uint32_t w_length;\
4856 : uint8_t *w_data;\
4857 : torture_assert(tctx,\
4858 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4859 : &w_type, &w_size, &w_length, &w_data),\
4860 : "failed to query winreg");\
4861 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4862 : blob = data_blob(w_data, w_size);\
4863 : ndr_err = ndr_pull_struct_blob(&blob, tctx, &dm,\
4864 : (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);\
4865 : torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall dm");\
4866 : torture_assert(tctx, test_devicemode_equal(tctx, &dm, iname),\
4867 : "dm unequal");\
4868 : } while(0);
4869 :
4870 : #define test_sd(wname, iname) \
4871 : do {\
4872 : DATA_BLOB blob;\
4873 : struct security_descriptor sd;\
4874 : enum ndr_err_code ndr_err;\
4875 : enum winreg_Type w_type;\
4876 : uint32_t w_size;\
4877 : uint32_t w_length;\
4878 : uint8_t *w_data;\
4879 : torture_assert(tctx,\
4880 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4881 : &w_type, &w_size, &w_length, &w_data),\
4882 : "failed to query winreg");\
4883 : torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
4884 : blob = data_blob(w_data, w_size);\
4885 : ndr_err = ndr_pull_struct_blob(&blob, tctx, &sd,\
4886 : (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);\
4887 : torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall sd");\
4888 : torture_assert(tctx, test_security_descriptor_equal(tctx, &sd, iname),\
4889 : "sd unequal");\
4890 : } while(0);
4891 :
4892 : #define test_multi_sz(wname, iname) \
4893 : do {\
4894 : DATA_BLOB blob;\
4895 : const char **array;\
4896 : enum winreg_Type w_type;\
4897 : uint32_t w_size;\
4898 : uint32_t w_length;\
4899 : uint8_t *w_data;\
4900 : int i;\
4901 : torture_assert(tctx,\
4902 : test_winreg_QueryValue(tctx, winreg_handle, &key_handle, wname,\
4903 : &w_type, &w_size, &w_length, &w_data),\
4904 : "failed to query winreg");\
4905 : torture_assert_int_equal(tctx, w_type, REG_MULTI_SZ, "unexpected type");\
4906 : blob = data_blob(w_data, w_size);\
4907 : torture_assert(tctx, \
4908 : pull_reg_multi_sz(tctx, &blob, &array),\
4909 : "failed to pull multi sz");\
4910 : for (i=0; array[i] != NULL; i++) {\
4911 : torture_assert_str_equal(tctx, array[i], iname[i],\
4912 : talloc_asprintf(tctx, "%s - %s mismatch", #wname, iname[i]));\
4913 : }\
4914 : } while(0);
4915 :
4916 0 : if (!test_winreg_symbolic_link(tctx, winreg_handle, hive_handle,
4917 : TOP_LEVEL_CONTROL_PRINTERS_KEY,
4918 : "\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"))
4919 : {
4920 0 : torture_warning(tctx, "failed to check for winreg symlink");
4921 : }
4922 :
4923 0 : for (i=0; i < ARRAY_SIZE(keys); i++) {
4924 :
4925 : const char *printer_key;
4926 : struct policy_handle key_handle;
4927 :
4928 0 : printer_key = talloc_asprintf(tctx, "%s\\%s",
4929 : keys[i], printer_name);
4930 :
4931 0 : torture_assert(tctx,
4932 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle, printer_key, &key_handle), "");
4933 :
4934 0 : test_sz("Name", printername);
4935 0 : test_sz("Share Name", sharename);
4936 0 : test_sz("Port", info.info2.portname);
4937 0 : test_sz("Printer Driver", info.info2.drivername);
4938 0 : test_sz("Description", info.info2.comment);
4939 0 : test_sz("Location", info.info2.location);
4940 0 : test_sz("Separator File", info.info2.sepfile);
4941 0 : test_sz("Print Processor", info.info2.printprocessor);
4942 0 : test_sz("Datatype", info.info2.datatype);
4943 0 : test_sz("Parameters", info.info2.parameters);
4944 : /* winreg: 0, spoolss not */
4945 : /* test_dword("Attributes", info.info2.attributes); */
4946 0 : test_dword("Priority", info.info2.priority);
4947 0 : test_dword("Default Priority", info.info2.defaultpriority);
4948 : /* winreg: 60, spoolss: 0 */
4949 : /* test_dword("StartTime", info.info2.starttime); */
4950 : /* test_dword("UntilTime", info.info2.untiltime); */
4951 : /* winreg != spoolss */
4952 : /* test_dword("Status", info.info2.status); */
4953 0 : test_dm("Default DevMode", info.info2.devmode);
4954 0 : test_sd("Security", info.info2.secdesc);
4955 :
4956 0 : torture_assert(tctx,
4957 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
4958 : }
4959 :
4960 : #undef test_dm
4961 :
4962 0 : torture_comment(tctx, "Printer Info and winreg consistency test succeeded\n\n");
4963 :
4964 0 : return true;
4965 : }
4966 :
4967 0 : static bool test_GetPrintserverInfo_winreg(struct torture_context *tctx,
4968 : struct dcerpc_binding_handle *b,
4969 : struct policy_handle *handle,
4970 : struct dcerpc_binding_handle *winreg_handle,
4971 : struct policy_handle *hive_handle)
4972 : {
4973 : union spoolss_PrinterInfo info;
4974 : struct policy_handle key_handle;
4975 :
4976 0 : torture_comment(tctx,
4977 : "Testing Printserver Info and winreg consistency\n");
4978 :
4979 0 : torture_assert(tctx,
4980 : test_GetPrinter_level(tctx, b, handle, 3, &info),
4981 : "failed to get printer info level 2");
4982 :
4983 0 : torture_assert(tctx,
4984 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle,
4985 : TOP_LEVEL_CONTROL_KEY, &key_handle), "");
4986 :
4987 0 : test_sd("ServerSecurityDescriptor", info.info3.secdesc);
4988 :
4989 0 : torture_assert(tctx,
4990 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
4991 :
4992 : #undef test_sd
4993 :
4994 0 : torture_comment(tctx,
4995 : "Printserver Info and winreg consistency test succeeded\n\n");
4996 :
4997 0 : return true;
4998 : }
4999 :
5000 :
5001 0 : static bool test_PrintProcessors(struct torture_context *tctx,
5002 : struct dcerpc_binding_handle *b,
5003 : const char *environment,
5004 : struct dcerpc_binding_handle *winreg_handle,
5005 : struct policy_handle *hive_handle)
5006 : {
5007 : union spoolss_PrintProcessorInfo *info;
5008 : uint32_t count;
5009 : int i;
5010 :
5011 0 : torture_comment(tctx, "Testing Print Processor Info and winreg consistency\n");
5012 :
5013 0 : torture_assert(tctx,
5014 : test_EnumPrintProcessors_level(tctx, b, environment, 1, &count, &info, WERR_OK),
5015 : "failed to enum print processors level 1");
5016 :
5017 0 : for (i=0; i < count; i++) {
5018 :
5019 : const char *processor_key;
5020 : struct policy_handle key_handle;
5021 :
5022 0 : processor_key = talloc_asprintf(tctx, "%s\\%s\\Print Processors\\%s",
5023 : TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY,
5024 : environment,
5025 0 : info[i].info1.print_processor_name);
5026 :
5027 0 : torture_assert(tctx,
5028 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle, processor_key, &key_handle), "");
5029 :
5030 : /* nothing to check in there so far */
5031 :
5032 0 : torture_assert(tctx,
5033 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
5034 : }
5035 :
5036 0 : torture_comment(tctx, "Print Processor Info and winreg consistency test succeeded\n\n");
5037 :
5038 0 : return true;
5039 : }
5040 :
5041 : static bool test_GetPrinterDriver2_level(struct torture_context *tctx,
5042 : struct dcerpc_binding_handle *b,
5043 : struct policy_handle *handle,
5044 : const char *driver_name,
5045 : const char *architecture,
5046 : uint32_t level,
5047 : uint32_t client_major_version,
5048 : uint32_t client_minor_version,
5049 : union spoolss_DriverInfo *info_p,
5050 : WERROR *result);
5051 :
5052 0 : static const char *strip_path(const char *path)
5053 : {
5054 : char *p;
5055 :
5056 0 : if (path == NULL) {
5057 0 : return NULL;
5058 : }
5059 :
5060 0 : p = strrchr(path, '\\');
5061 0 : if (p) {
5062 0 : return p+1;
5063 : }
5064 :
5065 0 : return path;
5066 : }
5067 :
5068 0 : static const char **strip_paths(const char **path_array)
5069 : {
5070 : int i;
5071 :
5072 0 : if (path_array == NULL) {
5073 0 : return NULL;
5074 : }
5075 :
5076 0 : for (i=0; path_array[i] != NULL; i++) {
5077 0 : path_array[i] = strip_path(path_array[i]);
5078 : }
5079 :
5080 0 : return path_array;
5081 : }
5082 :
5083 0 : static const char *driver_winreg_date(TALLOC_CTX *mem_ctx, NTTIME nt)
5084 : {
5085 : time_t t;
5086 : struct tm *tm;
5087 :
5088 0 : if (nt == 0) {
5089 0 : return talloc_strdup(mem_ctx, "01/01/1601");
5090 : }
5091 :
5092 0 : t = nt_time_to_unix(nt);
5093 0 : tm = localtime(&t);
5094 :
5095 0 : return talloc_asprintf(mem_ctx, "%02d/%02d/%04d",
5096 0 : tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
5097 : }
5098 :
5099 0 : static const char *driver_winreg_version(TALLOC_CTX *mem_ctx, uint64_t v)
5100 : {
5101 0 : return talloc_asprintf(mem_ctx, "%u.%u.%u.%u",
5102 0 : (unsigned)((v >> 48) & 0xFFFF),
5103 0 : (unsigned)((v >> 32) & 0xFFFF),
5104 0 : (unsigned)((v >> 16) & 0xFFFF),
5105 : (unsigned)(v & 0xFFFF));
5106 : }
5107 :
5108 0 : static bool test_GetDriverInfo_winreg(struct torture_context *tctx,
5109 : struct dcerpc_binding_handle *b,
5110 : struct policy_handle *handle,
5111 : const char *printer_name,
5112 : const char *driver_name,
5113 : const char *environment,
5114 : enum spoolss_DriverOSVersion version,
5115 : struct dcerpc_binding_handle *winreg_handle,
5116 : struct policy_handle *hive_handle,
5117 : const char *server_name_slash)
5118 : {
5119 0 : WERROR result = WERR_OK;
5120 : union spoolss_DriverInfo info;
5121 : const char *driver_key;
5122 : struct policy_handle key_handle;
5123 :
5124 : const char *driver_path;
5125 : const char *data_file;
5126 : const char *config_file;
5127 : const char *help_file;
5128 : const char **dependent_files;
5129 :
5130 : const char *driver_date;
5131 : const char *inbox_driver_date;
5132 :
5133 : const char *driver_version;
5134 : const char *inbox_driver_version;
5135 :
5136 0 : ZERO_STRUCT(key_handle);
5137 :
5138 0 : torture_comment(tctx, "Testing Driver Info and winreg consistency\n");
5139 :
5140 0 : driver_key = talloc_asprintf(tctx, "%s\\%s\\Drivers\\Version-%d\\%s",
5141 : TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY,
5142 : environment,
5143 : version,
5144 : driver_name);
5145 :
5146 0 : torture_assert(tctx,
5147 : test_winreg_OpenKey(tctx, winreg_handle, hive_handle, driver_key, &key_handle),
5148 : "failed to open driver key");
5149 :
5150 0 : if (torture_setting_bool(tctx, "samba3", false) ||
5151 0 : torture_setting_bool(tctx, "w2k3", false)) {
5152 0 : goto try_level6;
5153 : }
5154 :
5155 0 : if (handle) {
5156 0 : torture_assert(tctx,
5157 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, environment, 8, version, 0, &info, &result),
5158 : "failed to get driver info level 8");
5159 : } else {
5160 0 : torture_assert(tctx,
5161 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, environment, 8, driver_name, &info),
5162 : "failed to get driver info level 8");
5163 : }
5164 :
5165 0 : if (W_ERROR_EQUAL(result, WERR_INVALID_LEVEL)) {
5166 0 : goto try_level6;
5167 : }
5168 :
5169 0 : driver_path = strip_path(info.info8.driver_path);
5170 0 : data_file = strip_path(info.info8.data_file);
5171 0 : config_file = strip_path(info.info8.config_file);
5172 0 : help_file = strip_path(info.info8.help_file);
5173 0 : dependent_files = strip_paths(info.info8.dependent_files);
5174 :
5175 0 : driver_date = driver_winreg_date(tctx, info.info8.driver_date);
5176 0 : inbox_driver_date = driver_winreg_date(tctx, info.info8.min_inbox_driver_ver_date);
5177 :
5178 0 : driver_version = driver_winreg_version(tctx, info.info8.driver_version);
5179 0 : inbox_driver_version = driver_winreg_version(tctx, info.info8.min_inbox_driver_ver_version);
5180 :
5181 0 : test_sz("Configuration File", config_file);
5182 0 : test_sz("Data File", data_file);
5183 0 : test_sz("Datatype", info.info8.default_datatype);
5184 0 : test_sz("Driver", driver_path);
5185 0 : test_sz("DriverDate", driver_date);
5186 0 : test_sz("DriverVersion", driver_version);
5187 0 : test_sz("HardwareID", info.info8.hardware_id);
5188 0 : test_sz("Help File", help_file);
5189 0 : test_sz("InfPath", info.info8.inf_path);
5190 0 : test_sz("Manufacturer", info.info8.manufacturer_name);
5191 0 : test_sz("MinInboxDriverVerDate", inbox_driver_date);
5192 0 : test_sz("MinInboxDriverVerVersion", inbox_driver_version);
5193 0 : test_sz("Monitor", info.info8.monitor_name);
5194 0 : test_sz("OEM URL", info.info8.manufacturer_url);
5195 0 : test_sz("Print Processor", info.info8.print_processor);
5196 0 : test_sz("Provider", info.info8.provider);
5197 0 : test_sz("VendorSetup", info.info8.vendor_setup);
5198 0 : test_multi_sz("ColorProfiles", info.info8.color_profiles);
5199 0 : test_multi_sz("Dependent Files", dependent_files);
5200 0 : test_multi_sz("CoreDependencies", info.info8.core_driver_dependencies);
5201 0 : test_multi_sz("Previous Names", info.info8.previous_names);
5202 : /* test_dword("Attributes", ?); */
5203 0 : test_dword("PrinterDriverAttributes", info.info8.printer_driver_attributes);
5204 0 : test_dword("Version", info.info8.version);
5205 : /* test_dword("TempDir", ?); */
5206 :
5207 0 : try_level6:
5208 :
5209 0 : if (handle) {
5210 0 : torture_assert(tctx,
5211 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, environment, 6, version, 0, &info, &result),
5212 : "failed to get driver info level 6");
5213 : } else {
5214 0 : torture_assert(tctx,
5215 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, environment, 6, driver_name, &info),
5216 : "failed to get driver info level 6");
5217 : }
5218 :
5219 0 : driver_path = strip_path(info.info6.driver_path);
5220 0 : data_file = strip_path(info.info6.data_file);
5221 0 : config_file = strip_path(info.info6.config_file);
5222 0 : help_file = strip_path(info.info6.help_file);
5223 0 : dependent_files = strip_paths(info.info6.dependent_files);
5224 :
5225 0 : driver_date = driver_winreg_date(tctx, info.info6.driver_date);
5226 :
5227 0 : driver_version = driver_winreg_version(tctx, info.info6.driver_version);
5228 :
5229 0 : test_sz("Configuration File", config_file);
5230 0 : test_sz("Data File", data_file);
5231 0 : test_sz("Datatype", info.info6.default_datatype);
5232 0 : test_sz("Driver", driver_path);
5233 0 : if (torture_setting_bool(tctx, "w2k3", false)) {
5234 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 8);
5235 0 : push_nttime(blob.data, 0, info.info6.driver_date);
5236 0 : test_binary("DriverDate", blob);
5237 0 : SBVAL(blob.data, 0, info.info6.driver_version);
5238 0 : test_binary("DriverVersion", blob);
5239 : } else {
5240 0 : test_sz("DriverDate", driver_date);
5241 0 : test_sz("DriverVersion", driver_version);
5242 : }
5243 0 : test_sz("HardwareID", info.info6.hardware_id);
5244 0 : test_sz("Help File", help_file);
5245 0 : test_sz("Manufacturer", info.info6.manufacturer_name);
5246 0 : test_sz("Monitor", info.info6.monitor_name);
5247 0 : test_sz("OEM URL", info.info6.manufacturer_url);
5248 0 : test_sz("Provider", info.info6.provider);
5249 0 : test_multi_sz("Dependent Files", dependent_files);
5250 0 : test_multi_sz("Previous Names", info.info6.previous_names);
5251 : /* test_dword("Attributes", ?); */
5252 0 : test_dword("Version", info.info6.version);
5253 : /* test_dword("TempDir", ?); */
5254 :
5255 0 : if (handle) {
5256 0 : torture_assert(tctx,
5257 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, environment, 3, version, 0, &info, &result),
5258 : "failed to get driver info level 3");
5259 : } else {
5260 0 : torture_assert(tctx,
5261 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, environment, 3, driver_name, &info),
5262 : "failed to get driver info level 3");
5263 : }
5264 :
5265 0 : driver_path = strip_path(info.info3.driver_path);
5266 0 : data_file = strip_path(info.info3.data_file);
5267 0 : config_file = strip_path(info.info3.config_file);
5268 0 : help_file = strip_path(info.info3.help_file);
5269 0 : dependent_files = strip_paths(info.info3.dependent_files);
5270 :
5271 0 : test_sz("Configuration File", config_file);
5272 0 : test_sz("Data File", data_file);
5273 0 : test_sz("Datatype", info.info3.default_datatype);
5274 0 : test_sz("Driver", driver_path);
5275 0 : test_sz("Help File", help_file);
5276 0 : test_sz("Monitor", info.info3.monitor_name);
5277 0 : test_multi_sz("Dependent Files", dependent_files);
5278 : /* test_dword("Attributes", ?); */
5279 0 : test_dword("Version", info.info3.version);
5280 : /* test_dword("TempDir", ?); */
5281 :
5282 :
5283 0 : torture_assert(tctx,
5284 : test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
5285 :
5286 0 : torture_comment(tctx, "Driver Info and winreg consistency test succeeded\n\n");
5287 :
5288 0 : return true;
5289 : }
5290 :
5291 : #undef test_sz
5292 : #undef test_dword
5293 :
5294 0 : static bool test_SetPrinterData(struct torture_context *tctx,
5295 : struct dcerpc_binding_handle *b,
5296 : struct policy_handle *handle,
5297 : const char *value_name,
5298 : enum winreg_Type type,
5299 : uint8_t *data,
5300 : uint32_t offered)
5301 : {
5302 : struct spoolss_SetPrinterData r;
5303 :
5304 0 : r.in.handle = handle;
5305 0 : r.in.value_name = value_name;
5306 0 : r.in.type = type;
5307 0 : r.in.data = data;
5308 0 : r.in.offered = offered;
5309 :
5310 0 : torture_comment(tctx, "Testing SetPrinterData(%s)\n",
5311 : r.in.value_name);
5312 :
5313 0 : torture_assert_ntstatus_ok(tctx,
5314 : dcerpc_spoolss_SetPrinterData_r(b, tctx, &r),
5315 : "SetPrinterData failed");
5316 0 : torture_assert_werr_ok(tctx, r.out.result,
5317 : "SetPrinterData failed");
5318 :
5319 0 : return true;
5320 : }
5321 :
5322 0 : static bool test_SetPrinterData_matrix(struct torture_context *tctx,
5323 : struct dcerpc_binding_handle *b,
5324 : struct policy_handle *handle,
5325 : const char *printer_name,
5326 : struct dcerpc_binding_handle *winreg_handle,
5327 : struct policy_handle *hive_handle)
5328 : {
5329 0 : const char *values[] = {
5330 : "spootyfoot",
5331 : "spooty\\foot",
5332 : #if 0
5333 : /* FIXME: not working with s3 atm. */
5334 : "spooty,foot",
5335 : "spooty,fo,ot",
5336 : #endif
5337 : "spooty foot",
5338 : #if 0
5339 : /* FIXME: not working with s3 atm. */
5340 : "spooty\\fo,ot",
5341 : "spooty,fo\\ot"
5342 : #endif
5343 : };
5344 : int i;
5345 :
5346 0 : for (i=0; i < ARRAY_SIZE(values); i++) {
5347 :
5348 0 : enum winreg_Type type, expected_type = REG_SZ;
5349 : DATA_BLOB blob;
5350 : uint8_t *data;
5351 : uint32_t needed;
5352 :
5353 0 : torture_assert(tctx, push_reg_sz(tctx, &blob, "dog"), "");
5354 0 : type = REG_SZ;
5355 :
5356 0 : torture_assert(tctx,
5357 : test_SetPrinterData(tctx, b, handle, values[i], REG_SZ, blob.data, blob.length),
5358 : "SetPrinterData failed");
5359 :
5360 0 : torture_assert(tctx,
5361 : test_GetPrinterData_checktype(tctx, b, handle, values[i], &expected_type, &type, &data, &needed),
5362 : "GetPrinterData failed");
5363 :
5364 0 : torture_assert_int_equal(tctx, type, REG_SZ, "type mismatch");
5365 0 : torture_assert_int_equal(tctx, needed, blob.length, "size mismatch");
5366 0 : torture_assert_mem_equal(tctx, data, blob.data, blob.length, "buffer mismatch");
5367 :
5368 0 : if (winreg_handle && hive_handle) {
5369 :
5370 : enum winreg_Type w_type;
5371 : uint32_t w_size;
5372 : uint32_t w_length;
5373 : uint8_t *w_data;
5374 :
5375 0 : torture_assert(tctx,
5376 : test_winreg_query_printerdata(tctx, winreg_handle, hive_handle,
5377 : printer_name, "PrinterDriverData", values[i],
5378 : &w_type, &w_size, &w_length, &w_data), "");
5379 :
5380 0 : torture_assert_int_equal(tctx, w_type, REG_SZ, "winreg type mismatch");
5381 0 : torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
5382 0 : torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
5383 0 : torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
5384 : }
5385 :
5386 0 : torture_assert(tctx,
5387 : test_DeletePrinterData(tctx, b, handle, values[i]),
5388 : "DeletePrinterData failed");
5389 : }
5390 :
5391 0 : return true;
5392 : }
5393 :
5394 :
5395 : static bool test_EnumPrinterKey(struct torture_context *tctx,
5396 : struct dcerpc_binding_handle *b,
5397 : struct policy_handle *handle,
5398 : const char *key_name,
5399 : const char ***array);
5400 :
5401 0 : static bool test_SetPrinterDataEx(struct torture_context *tctx,
5402 : struct dcerpc_binding_handle *b,
5403 : struct policy_handle *handle,
5404 : const char *key_name,
5405 : const char *value_name,
5406 : enum winreg_Type type,
5407 : uint8_t *data,
5408 : uint32_t offered)
5409 : {
5410 : NTSTATUS status;
5411 : struct spoolss_SetPrinterDataEx r;
5412 :
5413 0 : r.in.handle = handle;
5414 0 : r.in.key_name = key_name;
5415 0 : r.in.value_name = value_name;
5416 0 : r.in.type = type;
5417 0 : r.in.data = data;
5418 0 : r.in.offered = offered;
5419 :
5420 0 : torture_comment(tctx, "Testing SetPrinterDataEx(%s - %s) type: %s, offered: 0x%08x\n",
5421 0 : r.in.key_name, r.in.value_name, str_regtype(r.in.type), r.in.offered);
5422 :
5423 0 : status = dcerpc_spoolss_SetPrinterDataEx_r(b, tctx, &r);
5424 :
5425 0 : torture_assert_ntstatus_ok(tctx, status, "SetPrinterDataEx failed");
5426 0 : torture_assert_werr_ok(tctx, r.out.result, "SetPrinterDataEx failed");
5427 :
5428 0 : return true;
5429 : }
5430 :
5431 0 : static bool test_SetPrinterDataEx_keys(struct torture_context *tctx,
5432 : struct dcerpc_pipe *p,
5433 : struct policy_handle *handle)
5434 : {
5435 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5436 0 : const char *value_name = "dog";
5437 0 : const char *keys[] = {
5438 : "torturedataex",
5439 : "torture data ex",
5440 : "torturedataex_with_subkey\\subkey",
5441 : "torturedataex_with_subkey\\subkey:0",
5442 : "torturedataex_with_subkey\\subkey:1",
5443 : "torturedataex_with_subkey\\subkey\\subsubkey",
5444 : "torturedataex_with_subkey\\subkey\\subsubkey:0",
5445 : "torturedataex_with_subkey\\subkey\\subsubkey:1",
5446 : "torture,data",
5447 : "torture,data,ex",
5448 : "torture,data\\ex",
5449 : "torture\\data,ex",
5450 : "torture/data",
5451 : "torture/data ex",
5452 : "torture/data ex/sub",
5453 : "torture//data",
5454 : "torture//data ex",
5455 : "torture//data ex/sub",
5456 : "torture//data ex//sub",
5457 : };
5458 : int i;
5459 :
5460 0 : for (i=0; i < ARRAY_SIZE(keys); i++) {
5461 :
5462 : char *c;
5463 : const char *key;
5464 : enum winreg_Type type;
5465 : DATA_BLOB blob_in, blob_out;
5466 : const char **subkeys;
5467 : uint32_t ecount;
5468 : struct spoolss_PrinterEnumValues *einfo;
5469 : uint32_t needed;
5470 :
5471 0 : blob_in = data_blob_talloc(tctx, NULL, 42);
5472 :
5473 0 : generate_random_buffer(blob_in.data, blob_in.length);
5474 :
5475 0 : torture_assert(tctx,
5476 : test_SetPrinterDataEx(tctx, b, handle, keys[i], value_name, REG_BINARY, blob_in.data, blob_in.length),
5477 : "failed to call SetPrinterDataEx");
5478 :
5479 0 : torture_assert(tctx,
5480 : test_GetPrinterDataEx(tctx, p, handle, keys[i], value_name, &type, &blob_out.data, &needed),
5481 : "failed to call GetPrinterDataEx");
5482 :
5483 0 : blob_out.length = needed;
5484 0 : torture_assert(tctx,
5485 : test_EnumPrinterDataEx(tctx, b, handle, keys[i], &ecount, &einfo),
5486 : "failed to call EnumPrinterDataEx");
5487 :
5488 0 : torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
5489 0 : torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
5490 0 : torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
5491 :
5492 0 : torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5493 0 : torture_assert_str_equal(tctx, einfo[0].value_name, value_name, "value_name mismatch");
5494 0 : torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(value_name)*2, "unexpected value_name_len");
5495 0 : torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
5496 0 : torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
5497 0 : if (einfo[0].data_length > 0) {
5498 0 : torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
5499 : }
5500 :
5501 0 : key = talloc_strdup(tctx, keys[i]);
5502 :
5503 0 : if (!test_DeletePrinterDataEx(tctx, b, handle, keys[i], value_name)) {
5504 0 : return false;
5505 : }
5506 :
5507 0 : c = strchr(key, '\\');
5508 0 : if (c) {
5509 : int k;
5510 :
5511 : /* we have subkeys */
5512 :
5513 0 : *c = 0;
5514 :
5515 0 : if (!test_EnumPrinterKey(tctx, b, handle, key, &subkeys)) {
5516 0 : return false;
5517 : }
5518 :
5519 0 : for (k=0; subkeys && subkeys[k]; k++) {
5520 :
5521 0 : const char *current_key = talloc_asprintf(tctx, "%s\\%s", key, subkeys[k]);
5522 :
5523 0 : if (!test_DeletePrinterKey(tctx, b, handle, current_key)) {
5524 0 : return false;
5525 : }
5526 : }
5527 :
5528 0 : if (!test_DeletePrinterKey(tctx, b, handle, key)) {
5529 0 : return false;
5530 : }
5531 :
5532 : } else {
5533 0 : if (!test_DeletePrinterKey(tctx, b, handle, key)) {
5534 0 : return false;
5535 : }
5536 : }
5537 : }
5538 :
5539 0 : return true;
5540 : }
5541 :
5542 0 : static bool test_SetPrinterDataEx_values(struct torture_context *tctx,
5543 : struct dcerpc_pipe *p,
5544 : struct policy_handle *handle)
5545 : {
5546 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5547 0 : const char *key = "torturedataex";
5548 0 : const char *values[] = {
5549 : "torture_value",
5550 : "torture value",
5551 : "torture,value",
5552 : "torture/value",
5553 : "torture\\value",
5554 : "torture\\\\value"
5555 : };
5556 : int i;
5557 :
5558 0 : for (i=0; i < ARRAY_SIZE(values); i++) {
5559 :
5560 0 : enum winreg_Type type = REG_NONE;
5561 0 : DATA_BLOB blob_in = data_blob_null;
5562 0 : DATA_BLOB blob_out = data_blob_null;
5563 : uint32_t ecount;
5564 : struct spoolss_PrinterEnumValues *einfo;
5565 0 : uint32_t needed = 0;
5566 :
5567 0 : if (torture_setting_bool(tctx, "samba3", false)) {
5568 : char *q;
5569 0 : q = strrchr(values[i], ',');
5570 0 : if (q) {
5571 0 : torture_comment(tctx, "skipping valuename '%s' including ',' character against Samba3\n",
5572 : values[i]);
5573 0 : continue;
5574 : }
5575 : }
5576 :
5577 0 : blob_in = data_blob_talloc(tctx, NULL, 42);
5578 :
5579 0 : generate_random_buffer(blob_in.data, blob_in.length);
5580 :
5581 0 : torture_assert(tctx,
5582 : test_SetPrinterDataEx(tctx, b, handle, key, values[i], REG_BINARY, blob_in.data, blob_in.length),
5583 : "failed to call SetPrinterDataEx");
5584 :
5585 0 : torture_assert(tctx,
5586 : test_GetPrinterDataEx(tctx, p, handle, key, values[i], &type, &blob_out.data, &needed),
5587 : "failed to call GetPrinterDataEx");
5588 :
5589 0 : blob_out.length = needed;
5590 0 : torture_assert(tctx,
5591 : test_EnumPrinterDataEx(tctx, b, handle, key, &ecount, &einfo),
5592 : "failed to call EnumPrinterDataEx");
5593 :
5594 0 : torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
5595 0 : torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
5596 0 : torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
5597 :
5598 0 : torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5599 0 : torture_assert_str_equal(tctx, einfo[0].value_name, values[i], "value_name mismatch");
5600 0 : torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(values[i])*2, "unexpected value_name_len");
5601 0 : torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
5602 0 : torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
5603 0 : if (einfo[0].data_length > 0) {
5604 0 : torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
5605 : }
5606 :
5607 0 : torture_assert(tctx,
5608 : test_DeletePrinterDataEx(tctx, b, handle, key, values[i]),
5609 : "failed to call DeletePrinterDataEx");
5610 : }
5611 :
5612 0 : return true;
5613 : }
5614 :
5615 :
5616 0 : static bool test_SetPrinterDataEx_matrix(struct torture_context *tctx,
5617 : struct dcerpc_pipe *p,
5618 : struct policy_handle *handle,
5619 : const char *printername,
5620 : struct dcerpc_binding_handle *winreg_handle,
5621 : struct policy_handle *hive_handle)
5622 : {
5623 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5624 0 : const char *value_name = "dog";
5625 0 : const char *key_name = "torturedataex";
5626 0 : enum winreg_Type types[] = {
5627 : REG_SZ,
5628 : REG_MULTI_SZ,
5629 : REG_DWORD,
5630 : REG_BINARY
5631 : };
5632 0 : const char *str = "abcdefghi";
5633 : size_t t, s;
5634 :
5635 0 : for (t=0; t < ARRAY_SIZE(types); t++) {
5636 0 : for (s=0; s < strlen(str); s++) {
5637 :
5638 : enum winreg_Type type;
5639 0 : const char *string = talloc_strndup(tctx, str, s);
5640 : const char *array[2];
5641 0 : DATA_BLOB blob = data_blob_string_const(string);
5642 : DATA_BLOB data;
5643 : uint8_t *data_out;
5644 0 : uint32_t needed, offered = 0;
5645 : uint32_t ecount;
5646 : struct spoolss_PrinterEnumValues *einfo;
5647 :
5648 0 : array[0] = talloc_strdup(tctx, string);
5649 0 : array[1] = NULL;
5650 :
5651 0 : if (types[t] == REG_DWORD) {
5652 0 : s = 0xffff;
5653 : }
5654 :
5655 0 : switch (types[t]) {
5656 0 : case REG_BINARY:
5657 0 : data = blob;
5658 0 : offered = blob.length;
5659 0 : break;
5660 0 : case REG_DWORD:
5661 0 : data = data_blob_talloc(tctx, NULL, 4);
5662 0 : SIVAL(data.data, 0, 0x12345678);
5663 0 : offered = 4;
5664 0 : break;
5665 0 : case REG_SZ:
5666 0 : torture_assert(tctx, push_reg_sz(tctx, &data, string), "");
5667 0 : type = REG_SZ;
5668 0 : offered = data.length;
5669 : /*strlen_m_term(data.string)*2;*/
5670 0 : break;
5671 0 : case REG_MULTI_SZ:
5672 0 : torture_assert(tctx, push_reg_multi_sz(tctx, &data, array), "");
5673 0 : type = REG_MULTI_SZ;
5674 0 : offered = data.length;
5675 0 : break;
5676 0 : default:
5677 0 : torture_fail(tctx, talloc_asprintf(tctx, "type %d untested\n", types[t]));
5678 : }
5679 :
5680 0 : torture_assert(tctx,
5681 : test_SetPrinterDataEx(tctx, b, handle, key_name, value_name, types[t], data.data, offered),
5682 : "failed to call SetPrinterDataEx");
5683 :
5684 0 : torture_assert(tctx,
5685 : test_GetPrinterDataEx_checktype(tctx, p, handle, key_name, value_name, &types[t], &type, &data_out, &needed),
5686 : "failed to call GetPrinterDataEx");
5687 :
5688 0 : torture_assert(tctx,
5689 : test_EnumPrinterDataEx(tctx, b, handle, key_name, &ecount, &einfo),
5690 : "failed to call EnumPrinterDataEx");
5691 :
5692 0 : torture_assert_int_equal(tctx, types[t], type, "type mismatch");
5693 0 : torture_assert_int_equal(tctx, needed, offered, "size mismatch");
5694 0 : torture_assert_mem_equal(tctx, data_out, data.data, offered, "buffer mismatch");
5695 :
5696 0 : torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
5697 0 : torture_assert_str_equal(tctx, einfo[0].value_name, value_name, "value_name mismatch");
5698 0 : torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(value_name)*2, "unexpected value_name_len");
5699 0 : torture_assert_int_equal(tctx, einfo[0].type, types[t], "type mismatch");
5700 0 : torture_assert_int_equal(tctx, einfo[0].data_length, offered, "size mismatch");
5701 0 : if (einfo[0].data_length > 0) {
5702 0 : torture_assert_mem_equal(tctx, einfo[0].data->data, data.data, offered, "buffer mismatch");
5703 : }
5704 :
5705 0 : if (winreg_handle && hive_handle) {
5706 : enum winreg_Type w_type;
5707 : uint32_t w_size;
5708 : uint32_t w_length;
5709 : uint8_t *w_data;
5710 :
5711 0 : torture_assert(tctx,
5712 : test_winreg_query_printerdata(tctx, winreg_handle, hive_handle,
5713 : printername, key_name, value_name,
5714 : &w_type, &w_size, &w_length, &w_data), "");
5715 :
5716 0 : torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
5717 0 : torture_assert_int_equal(tctx, w_size, offered, "winreg size mismatch");
5718 0 : torture_assert_int_equal(tctx, w_length, offered, "winreg length mismatch");
5719 0 : torture_assert_mem_equal(tctx, w_data, data.data, offered, "winreg buffer mismatch");
5720 : }
5721 :
5722 0 : torture_assert(tctx,
5723 : test_DeletePrinterDataEx(tctx, b, handle, key_name, value_name),
5724 : "failed to call DeletePrinterDataEx");
5725 : }
5726 : }
5727 :
5728 0 : return true;
5729 : }
5730 :
5731 0 : static bool test_PrinterData_winreg(struct torture_context *tctx,
5732 : struct dcerpc_pipe *p,
5733 : struct policy_handle *handle,
5734 : const char *printer_name)
5735 : {
5736 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5737 : struct dcerpc_pipe *p2;
5738 0 : bool ret = true;
5739 : struct policy_handle hive_handle;
5740 : struct dcerpc_binding_handle *b2;
5741 :
5742 0 : torture_assert_ntstatus_ok(tctx,
5743 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5744 : "could not open winreg pipe");
5745 0 : b2 = p2->binding_handle;
5746 :
5747 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5748 :
5749 0 : ret &= test_SetPrinterData_matrix(tctx, b, handle, printer_name, b2, &hive_handle);
5750 0 : ret &= test_SetPrinterDataEx_matrix(tctx, p, handle, printer_name, b2, &hive_handle);
5751 :
5752 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5753 :
5754 0 : talloc_free(p2);
5755 :
5756 0 : return ret;
5757 : }
5758 :
5759 0 : static bool test_Forms_winreg(struct torture_context *tctx,
5760 : struct dcerpc_binding_handle *b,
5761 : struct policy_handle *handle,
5762 : bool print_server,
5763 : const char *printer_name)
5764 : {
5765 : struct dcerpc_pipe *p2;
5766 0 : bool ret = true;
5767 : struct policy_handle hive_handle;
5768 : struct dcerpc_binding_handle *b2;
5769 :
5770 0 : torture_assert_ntstatus_ok(tctx,
5771 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5772 : "could not open winreg pipe");
5773 0 : b2 = p2->binding_handle;
5774 :
5775 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5776 :
5777 0 : ret = test_Forms(tctx, b, handle, print_server, printer_name, b2, &hive_handle);
5778 :
5779 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5780 :
5781 0 : talloc_free(p2);
5782 :
5783 0 : return ret;
5784 : }
5785 :
5786 0 : static bool test_PrinterInfo_winreg(struct torture_context *tctx,
5787 : struct dcerpc_pipe *p,
5788 : struct policy_handle *handle,
5789 : const char *printer_name)
5790 : {
5791 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5792 : struct dcerpc_pipe *p2;
5793 0 : bool ret = true;
5794 : struct policy_handle hive_handle;
5795 : struct dcerpc_binding_handle *b2;
5796 :
5797 0 : torture_assert_ntstatus_ok(tctx,
5798 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5799 : "could not open winreg pipe");
5800 0 : b2 = p2->binding_handle;
5801 :
5802 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5803 :
5804 0 : ret = test_GetPrinterInfo_winreg(tctx, b, handle, printer_name, b2, &hive_handle);
5805 :
5806 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5807 :
5808 0 : talloc_free(p2);
5809 :
5810 0 : return ret;
5811 : }
5812 :
5813 0 : static bool test_PrintserverInfo_winreg(struct torture_context *tctx,
5814 : struct dcerpc_pipe *p,
5815 : struct policy_handle *handle)
5816 : {
5817 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5818 : struct dcerpc_pipe *p2;
5819 0 : bool ret = true;
5820 : struct policy_handle hive_handle;
5821 : struct dcerpc_binding_handle *b2;
5822 :
5823 0 : torture_assert_ntstatus_ok(tctx,
5824 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5825 : "could not open winreg pipe");
5826 0 : b2 = p2->binding_handle;
5827 :
5828 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5829 :
5830 0 : ret = test_GetPrintserverInfo_winreg(tctx, b, handle, b2, &hive_handle);
5831 :
5832 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5833 :
5834 0 : talloc_free(p2);
5835 :
5836 0 : return ret;
5837 : }
5838 :
5839 :
5840 0 : static bool test_DriverInfo_winreg(struct torture_context *tctx,
5841 : struct dcerpc_pipe *p,
5842 : struct policy_handle *handle,
5843 : const char *printer_name,
5844 : const char *driver_name,
5845 : const char *environment,
5846 : enum spoolss_DriverOSVersion version)
5847 : {
5848 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5849 : struct dcerpc_pipe *p2;
5850 0 : bool ret = true;
5851 : struct policy_handle hive_handle;
5852 : struct dcerpc_binding_handle *b2;
5853 :
5854 0 : torture_assert_ntstatus_ok(tctx,
5855 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5856 : "could not open winreg pipe");
5857 0 : b2 = p2->binding_handle;
5858 :
5859 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5860 :
5861 0 : ret = test_GetDriverInfo_winreg(tctx, b, handle, printer_name, driver_name, environment, version, b2, &hive_handle, NULL);
5862 :
5863 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5864 :
5865 0 : talloc_free(p2);
5866 :
5867 0 : return ret;
5868 : }
5869 :
5870 0 : static bool test_PrintProcessors_winreg(struct torture_context *tctx,
5871 : struct dcerpc_binding_handle *b,
5872 : const char *environment)
5873 : {
5874 : struct dcerpc_pipe *p2;
5875 0 : bool ret = true;
5876 : struct policy_handle hive_handle;
5877 : struct dcerpc_binding_handle *b2;
5878 :
5879 0 : torture_assert_ntstatus_ok(tctx,
5880 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
5881 : "could not open winreg pipe");
5882 0 : b2 = p2->binding_handle;
5883 :
5884 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
5885 :
5886 0 : ret = test_PrintProcessors(tctx, b, environment, b2, &hive_handle);
5887 :
5888 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
5889 :
5890 0 : talloc_free(p2);
5891 :
5892 0 : return ret;
5893 : }
5894 :
5895 0 : static bool test_PrinterData_DsSpooler(struct torture_context *tctx,
5896 : struct dcerpc_pipe *p,
5897 : struct policy_handle *handle,
5898 : const char *printer_name)
5899 : {
5900 : struct spoolss_SetPrinterInfoCtr info_ctr;
5901 : struct spoolss_DevmodeContainer devmode_ctr;
5902 : struct sec_desc_buf secdesc_ctr;
5903 : union spoolss_SetPrinterInfo sinfo;
5904 : union spoolss_PrinterInfo info;
5905 0 : struct dcerpc_binding_handle *b = p->binding_handle;
5906 : const char *pname;
5907 :
5908 0 : ZERO_STRUCT(info_ctr);
5909 0 : ZERO_STRUCT(devmode_ctr);
5910 0 : ZERO_STRUCT(secdesc_ctr);
5911 :
5912 0 : torture_comment(tctx, "Testing DsSpooler <-> SetPrinter relations\n");
5913 :
5914 0 : torture_assert(tctx,
5915 : test_GetPrinter_level(tctx, b, handle, 2, &info),
5916 : "failed to query Printer level 2");
5917 :
5918 0 : torture_assert(tctx,
5919 : PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo),
5920 : "failed to convert");
5921 :
5922 0 : info_ctr.level = 2;
5923 0 : info_ctr.info = sinfo;
5924 :
5925 : #define TEST_SZ(wname, iname) \
5926 : do {\
5927 : enum winreg_Type type;\
5928 : uint8_t *data;\
5929 : uint32_t needed;\
5930 : DATA_BLOB blob;\
5931 : const char *str;\
5932 : torture_assert(tctx,\
5933 : test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5934 : "failed to query");\
5935 : torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5936 : blob = data_blob_const(data, needed);\
5937 : torture_assert(tctx,\
5938 : pull_reg_sz(tctx, &blob, &str),\
5939 : "failed to pull REG_SZ");\
5940 : torture_assert_str_equal(tctx, str, iname, "unexpected result");\
5941 : } while(0);
5942 :
5943 :
5944 : #define TEST_SET_SZ(wname, iname, val) \
5945 : do {\
5946 : enum winreg_Type type;\
5947 : uint8_t *data;\
5948 : uint32_t needed;\
5949 : DATA_BLOB blob;\
5950 : const char *str;\
5951 : sinfo.info2->iname = val;\
5952 : torture_assert(tctx,\
5953 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5954 : "failed to call SetPrinter");\
5955 : torture_assert(tctx,\
5956 : test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5957 : "failed to query");\
5958 : torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
5959 : blob = data_blob_const(data, needed);\
5960 : torture_assert(tctx,\
5961 : pull_reg_sz(tctx, &blob, &str),\
5962 : "failed to pull REG_SZ");\
5963 : torture_assert_str_equal(tctx, str, val, "unexpected result");\
5964 : } while(0);
5965 :
5966 : #define TEST_SET_DWORD(wname, iname, val) \
5967 : do {\
5968 : enum winreg_Type type;\
5969 : uint8_t *data;\
5970 : uint32_t needed;\
5971 : uint32_t value;\
5972 : sinfo.info2->iname = val;\
5973 : torture_assert(tctx,\
5974 : test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),\
5975 : "failed to call SetPrinter");\
5976 : torture_assert(tctx,\
5977 : test_GetPrinterDataEx(tctx, p, handle, "DsSpooler", wname, &type, &data, &needed),\
5978 : "failed to query");\
5979 : torture_assert_int_equal(tctx, type, REG_DWORD, "unexpected type");\
5980 : torture_assert_int_equal(tctx, needed, 4, "unexpected length");\
5981 : value = IVAL(data, 0); \
5982 : torture_assert_int_equal(tctx, value, val, "unexpected result");\
5983 : } while(0);
5984 :
5985 0 : TEST_SET_SZ("description", comment, "newval");
5986 0 : TEST_SET_SZ("location", location, "newval");
5987 0 : TEST_SET_SZ("driverName", drivername, "newval");
5988 : /* TEST_SET_DWORD("priority", priority, 25); */
5989 :
5990 0 : torture_assert(tctx,
5991 : test_GetPrinter_level(tctx, b, handle, 2, &info),
5992 : "failed to query Printer level 2");
5993 :
5994 0 : TEST_SZ("description", info.info2.comment);
5995 0 : TEST_SZ("driverName", info.info2.drivername);
5996 0 : TEST_SZ("location", info.info2.location);
5997 :
5998 0 : pname = strrchr(info.info2.printername, '\\');
5999 0 : if (pname == NULL) {
6000 0 : pname = info.info2.printername;
6001 : } else {
6002 0 : pname++;
6003 : }
6004 0 : TEST_SZ("printerName", pname);
6005 : /* TEST_SZ("printSeparatorFile", info.info2.sepfile); */
6006 : /* TEST_SZ("printShareName", info.info2.sharename); */
6007 :
6008 : /* FIXME gd: complete the list */
6009 :
6010 : #undef TEST_SZ
6011 : #undef TEST_SET_SZ
6012 : #undef TEST_DWORD
6013 :
6014 0 : torture_comment(tctx, "DsSpooler <-> SetPrinter relations test succeeded\n\n");
6015 :
6016 0 : return true;
6017 : }
6018 :
6019 0 : static bool test_print_processors_winreg(struct torture_context *tctx,
6020 : void *private_data)
6021 : {
6022 0 : struct test_spoolss_context *ctx =
6023 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6024 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6025 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6026 :
6027 0 : return test_PrintProcessors_winreg(tctx, b, ctx->environment);
6028 : }
6029 :
6030 0 : static bool test_AddPrintProcessor(struct torture_context *tctx,
6031 : struct dcerpc_binding_handle *b,
6032 : const char *environment,
6033 : const char *path_name,
6034 : const char *print_processor_name,
6035 : WERROR expected_error)
6036 : {
6037 : struct spoolss_AddPrintProcessor r;
6038 :
6039 0 : r.in.server = NULL;
6040 0 : r.in.architecture = environment;
6041 0 : r.in.path_name = path_name;
6042 0 : r.in.print_processor_name = print_processor_name;
6043 :
6044 0 : torture_comment(tctx, "Testing AddPrintProcessor(%s)\n",
6045 : print_processor_name);
6046 :
6047 0 : torture_assert_ntstatus_ok(tctx,
6048 : dcerpc_spoolss_AddPrintProcessor_r(b, tctx, &r),
6049 : "spoolss_AddPrintProcessor failed");
6050 0 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6051 : "spoolss_AddPrintProcessor failed");
6052 :
6053 0 : return true;
6054 : }
6055 :
6056 0 : static bool test_DeletePrintProcessor(struct torture_context *tctx,
6057 : struct dcerpc_binding_handle *b,
6058 : const char *environment,
6059 : const char *print_processor_name,
6060 : WERROR expected_error)
6061 : {
6062 : struct spoolss_DeletePrintProcessor r;
6063 :
6064 0 : r.in.server = NULL;
6065 0 : r.in.architecture = environment;
6066 0 : r.in.print_processor_name = print_processor_name;
6067 :
6068 0 : torture_comment(tctx, "Testing DeletePrintProcessor(%s)\n",
6069 : print_processor_name);
6070 :
6071 0 : torture_assert_ntstatus_ok(tctx,
6072 : dcerpc_spoolss_DeletePrintProcessor_r(b, tctx, &r),
6073 : "spoolss_DeletePrintProcessor failed");
6074 0 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6075 : "spoolss_DeletePrintProcessor failed");
6076 :
6077 0 : return true;
6078 : }
6079 :
6080 0 : static bool test_add_print_processor(struct torture_context *tctx,
6081 : void *private_data)
6082 : {
6083 0 : struct test_spoolss_context *ctx =
6084 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6085 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6086 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6087 : int i;
6088 :
6089 : struct {
6090 : const char *environment;
6091 : const char *path_name;
6092 : const char *print_processor_name;
6093 : WERROR expected_add_result;
6094 : WERROR expected_del_result;
6095 0 : } tests[] = {
6096 : {
6097 0 : .environment = ctx->environment,
6098 : .path_name = "",
6099 : .print_processor_name = "winprint",
6100 : .expected_add_result = WERR_PRINT_PROCESSOR_ALREADY_INSTALLED,
6101 : .expected_del_result = WERR_CAN_NOT_COMPLETE
6102 : },{
6103 0 : .environment = ctx->environment,
6104 : .path_name = "",
6105 : .print_processor_name = "unknown",
6106 : .expected_add_result = WERR_MOD_NOT_FOUND,
6107 : .expected_del_result = WERR_UNKNOWN_PRINTPROCESSOR
6108 : }
6109 : };
6110 :
6111 0 : for (i=0; i < ARRAY_SIZE(tests); i++) {
6112 0 : torture_assert(tctx,
6113 : test_AddPrintProcessor(tctx, b,
6114 : tests[i].environment,
6115 : tests[i].path_name,
6116 : tests[i].print_processor_name,
6117 : tests[i].expected_add_result),
6118 : "add print processor failed");
6119 0 : torture_assert(tctx,
6120 : test_DeletePrintProcessor(tctx, b,
6121 : tests[i].environment,
6122 : tests[i].print_processor_name,
6123 : tests[i].expected_del_result),
6124 : "delete print processor failed");
6125 : }
6126 :
6127 0 : return true;
6128 : }
6129 :
6130 0 : static bool test_AddPerMachineConnection(struct torture_context *tctx,
6131 : struct dcerpc_binding_handle *b,
6132 : const char *servername,
6133 : const char *printername,
6134 : const char *printserver,
6135 : const char *provider,
6136 : WERROR expected_error)
6137 : {
6138 : struct spoolss_AddPerMachineConnection r;
6139 0 : const char *composed_printername = printername;
6140 :
6141 0 : if (servername != NULL) {
6142 0 : composed_printername = talloc_asprintf(tctx, "%s\\%s",
6143 : servername,
6144 : printername);
6145 : }
6146 0 : r.in.server = servername;
6147 0 : r.in.printername = composed_printername;
6148 0 : r.in.printserver = printserver;
6149 0 : r.in.provider = provider;
6150 :
6151 0 : torture_comment(tctx, "Testing AddPerMachineConnection(%s|%s|%s)\n",
6152 : printername, printserver, provider);
6153 :
6154 0 : torture_assert_ntstatus_ok(tctx,
6155 : dcerpc_spoolss_AddPerMachineConnection_r(b, tctx, &r),
6156 : "spoolss_AddPerMachineConnection failed");
6157 0 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6158 : "spoolss_AddPerMachineConnection failed");
6159 :
6160 0 : return true;
6161 : }
6162 :
6163 0 : static bool test_DeletePerMachineConnection(struct torture_context *tctx,
6164 : struct dcerpc_binding_handle *b,
6165 : const char *servername,
6166 : const char *printername,
6167 : WERROR expected_error)
6168 : {
6169 : struct spoolss_DeletePerMachineConnection r;
6170 0 : const char *composed_printername = printername;
6171 :
6172 0 : if (servername != NULL) {
6173 0 : composed_printername = talloc_asprintf(tctx, "%s\\%s",
6174 : servername,
6175 : printername);
6176 : }
6177 :
6178 0 : r.in.server = servername;
6179 0 : r.in.printername = composed_printername;
6180 :
6181 0 : torture_comment(tctx, "Testing DeletePerMachineConnection(%s)\n",
6182 : printername);
6183 :
6184 0 : torture_assert_ntstatus_ok(tctx,
6185 : dcerpc_spoolss_DeletePerMachineConnection_r(b, tctx, &r),
6186 : "spoolss_DeletePerMachineConnection failed");
6187 0 : torture_assert_werr_equal(tctx, r.out.result, expected_error,
6188 : "spoolss_DeletePerMachineConnection failed");
6189 :
6190 0 : return true;
6191 : }
6192 :
6193 0 : static bool test_EnumPerMachineConnections(struct torture_context *tctx,
6194 : struct dcerpc_binding_handle *b,
6195 : const char *servername)
6196 : {
6197 : struct spoolss_EnumPerMachineConnections r;
6198 0 : DATA_BLOB blob = data_blob_null;
6199 : struct spoolss_PrinterInfo4 *info;
6200 : uint32_t needed;
6201 : uint32_t count;
6202 :
6203 0 : r.in.server = servername;
6204 0 : r.in.buffer = &blob;
6205 0 : r.in.offered = 0;
6206 :
6207 0 : r.out.info = &info;
6208 0 : r.out.needed = &needed;
6209 0 : r.out.count = &count;
6210 :
6211 0 : torture_comment(tctx, "Testing EnumPerMachineConnections(%s)\n",
6212 : servername);
6213 :
6214 0 : torture_assert_ntstatus_ok(tctx,
6215 : dcerpc_spoolss_EnumPerMachineConnections_r(b, tctx, &r),
6216 : "spoolss_EnumPerMachineConnections failed");
6217 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
6218 0 : blob = data_blob_talloc_zero(tctx, needed);
6219 0 : r.in.buffer = &blob;
6220 0 : r.in.offered = needed;
6221 :
6222 0 : torture_assert_ntstatus_ok(tctx,
6223 : dcerpc_spoolss_EnumPerMachineConnections_r(b, tctx, &r),
6224 : "spoolss_EnumPerMachineConnections failed");
6225 : }
6226 0 : torture_assert_werr_ok(tctx, r.out.result,
6227 : "spoolss_EnumPerMachineConnections failed");
6228 :
6229 0 : return true;
6230 : }
6231 :
6232 0 : static bool test_addpermachineconnection(struct torture_context *tctx,
6233 : void *private_data)
6234 : {
6235 0 : struct test_spoolss_context *ctx =
6236 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6237 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6238 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6239 0 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
6240 : int i;
6241 :
6242 : struct {
6243 : const char *servername;
6244 : const char *printername;
6245 : const char *printserver;
6246 : const char *provider;
6247 : WERROR expected_add_result;
6248 : WERROR expected_del_result;
6249 0 : } tests[] = {
6250 : {
6251 : .servername = NULL,
6252 : .printername = "foo",
6253 : .printserver = "",
6254 : .provider = "unknown",
6255 : .expected_add_result = WERR_INVALID_PRINTER_NAME,
6256 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6257 : },{
6258 : .servername = NULL,
6259 : .printername = "Microsoft Print to PDF",
6260 : .printserver = "samba.org",
6261 : .provider = "unknown",
6262 : .expected_add_result = WERR_INVALID_PRINTER_NAME,
6263 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6264 : },{
6265 : .servername = NULL,
6266 : .printername = "Microsoft Print to PDF",
6267 : .printserver = "samba.org",
6268 : .provider = "",
6269 : .expected_add_result = WERR_INVALID_PRINTER_NAME,
6270 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6271 : },{
6272 : .servername = server_name_slash,
6273 : .printername = "foo",
6274 : .printserver = "",
6275 : .provider = "unknown",
6276 : .expected_add_result = WERR_FILE_NOT_FOUND,
6277 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6278 : },{
6279 : .servername = server_name_slash,
6280 : .printername = "foo",
6281 : .printserver = "",
6282 : .provider = "",
6283 : .expected_add_result = WERR_OK,
6284 : .expected_del_result = WERR_OK
6285 : },{
6286 : .servername = server_name_slash,
6287 : .printername = "Microsoft Print to PDF",
6288 : .printserver = "samba.org",
6289 : .provider = "unknown",
6290 : .expected_add_result = WERR_FILE_NOT_FOUND,
6291 : .expected_del_result = WERR_INVALID_PRINTER_NAME
6292 : },{
6293 : .servername = server_name_slash,
6294 : .printername = "Microsoft Print to PDF",
6295 : .printserver = "samba.org",
6296 : .provider = "",
6297 : .expected_add_result = WERR_OK,
6298 : .expected_del_result = WERR_OK
6299 : }
6300 : };
6301 :
6302 0 : for (i=0; i < ARRAY_SIZE(tests); i++) {
6303 0 : torture_assert(tctx,
6304 : test_AddPerMachineConnection(tctx, b,
6305 : tests[i].servername,
6306 : tests[i].printername,
6307 : tests[i].printserver,
6308 : tests[i].provider,
6309 : tests[i].expected_add_result),
6310 : "add per machine connection failed");
6311 0 : torture_assert(tctx,
6312 : test_EnumPerMachineConnections(tctx, b,
6313 : tests[i].servername),
6314 : "enum per machine connections failed");
6315 0 : torture_assert(tctx,
6316 : test_DeletePerMachineConnection(tctx, b,
6317 : tests[i].servername,
6318 : tests[i].printername,
6319 : tests[i].expected_del_result),
6320 : "delete per machine connection failed");
6321 0 : torture_assert(tctx,
6322 : test_EnumPerMachineConnections(tctx, b,
6323 : tests[i].servername),
6324 : "enum per machine connections failed");
6325 : }
6326 :
6327 0 : return true;
6328 : }
6329 :
6330 0 : static bool test_GetChangeID_PrinterData(struct torture_context *tctx,
6331 : struct dcerpc_binding_handle *b,
6332 : struct policy_handle *handle,
6333 : uint32_t *change_id)
6334 : {
6335 : enum winreg_Type type;
6336 : uint8_t *data;
6337 : uint32_t needed;
6338 :
6339 0 : torture_assert(tctx,
6340 : test_GetPrinterData(tctx, b, handle, "ChangeID", &type, &data, &needed),
6341 : "failed to call GetPrinterData");
6342 :
6343 0 : torture_assert(tctx, type == REG_DWORD, "unexpected type");
6344 0 : torture_assert_int_equal(tctx, needed, 4, "unexpected size");
6345 :
6346 0 : *change_id = IVAL(data, 0);
6347 :
6348 0 : return true;
6349 : }
6350 :
6351 0 : static bool test_GetChangeID_PrinterDataEx(struct torture_context *tctx,
6352 : struct dcerpc_pipe *p,
6353 : struct policy_handle *handle,
6354 : uint32_t *change_id)
6355 : {
6356 0 : enum winreg_Type type = REG_NONE;
6357 0 : uint8_t *data = NULL;
6358 0 : uint32_t needed = 0;
6359 :
6360 0 : torture_assert(tctx,
6361 : test_GetPrinterDataEx(tctx, p, handle, "PrinterDriverData", "ChangeID", &type, &data, &needed),
6362 : "failed to call GetPrinterData");
6363 :
6364 0 : torture_assert(tctx, type == REG_DWORD, "unexpected type");
6365 0 : torture_assert_int_equal(tctx, needed, 4, "unexpected size");
6366 :
6367 0 : *change_id = IVAL(data, 0);
6368 :
6369 0 : return true;
6370 : }
6371 :
6372 0 : static bool test_GetChangeID_PrinterInfo(struct torture_context *tctx,
6373 : struct dcerpc_binding_handle *b,
6374 : struct policy_handle *handle,
6375 : uint32_t *change_id)
6376 : {
6377 : union spoolss_PrinterInfo info;
6378 :
6379 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 0, &info),
6380 : "failed to query Printer level 0");
6381 :
6382 0 : *change_id = info.info0.change_id;
6383 :
6384 0 : return true;
6385 : }
6386 :
6387 0 : static bool test_ChangeID(struct torture_context *tctx,
6388 : struct dcerpc_pipe *p,
6389 : struct policy_handle *handle)
6390 : {
6391 : uint32_t change_id, change_id_ex, change_id_info;
6392 : uint32_t change_id2, change_id_ex2, change_id_info2;
6393 : union spoolss_PrinterInfo info;
6394 : const char *comment;
6395 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6396 :
6397 0 : torture_comment(tctx, "Testing ChangeID: id change test #1\n");
6398 :
6399 0 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
6400 : "failed to query for ChangeID");
6401 0 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
6402 : "failed to query for ChangeID");
6403 0 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
6404 : "failed to query for ChangeID");
6405 :
6406 0 : torture_assert_int_equal(tctx, change_id, change_id_ex,
6407 : "change_ids should all be equal");
6408 0 : torture_assert_int_equal(tctx, change_id_ex, change_id_info,
6409 : "change_ids should all be equal");
6410 :
6411 :
6412 0 : torture_comment(tctx, "Testing ChangeID: id change test #2\n");
6413 :
6414 0 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
6415 : "failed to query for ChangeID");
6416 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
6417 : "failed to query Printer level 2");
6418 0 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
6419 : "failed to query for ChangeID");
6420 0 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
6421 : "failed to query for ChangeID");
6422 0 : torture_assert_int_equal(tctx, change_id, change_id_ex,
6423 : "change_id should not have changed");
6424 0 : torture_assert_int_equal(tctx, change_id_ex, change_id_info,
6425 : "change_id should not have changed");
6426 :
6427 :
6428 0 : torture_comment(tctx, "Testing ChangeID: id change test #3\n");
6429 :
6430 0 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id),
6431 : "failed to query for ChangeID");
6432 0 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
6433 : "failed to query for ChangeID");
6434 0 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info),
6435 : "failed to query for ChangeID");
6436 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info),
6437 : "failed to query Printer level 2");
6438 0 : comment = talloc_strdup(tctx, info.info2.comment);
6439 :
6440 : {
6441 : struct spoolss_SetPrinterInfoCtr info_ctr;
6442 : struct spoolss_DevmodeContainer devmode_ctr;
6443 : struct sec_desc_buf secdesc_ctr;
6444 : union spoolss_SetPrinterInfo sinfo;
6445 :
6446 0 : ZERO_STRUCT(info_ctr);
6447 0 : ZERO_STRUCT(devmode_ctr);
6448 0 : ZERO_STRUCT(secdesc_ctr);
6449 :
6450 :
6451 0 : torture_assert(tctx, PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
6452 0 : sinfo.info2->comment = "torture_comment";
6453 :
6454 0 : info_ctr.level = 2;
6455 0 : info_ctr.info = sinfo;
6456 :
6457 0 : torture_assert(tctx, test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
6458 : "failed to call SetPrinter");
6459 :
6460 0 : sinfo.info2->comment = comment;
6461 :
6462 0 : torture_assert(tctx, test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
6463 : "failed to call SetPrinter");
6464 :
6465 : }
6466 :
6467 0 : torture_assert(tctx, test_GetChangeID_PrinterData(tctx, b, handle, &change_id2),
6468 : "failed to query for ChangeID");
6469 0 : torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex2),
6470 : "failed to query for ChangeID");
6471 0 : torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, b, handle, &change_id_info2),
6472 : "failed to query for ChangeID");
6473 :
6474 0 : torture_assert_int_equal(tctx, change_id2, change_id_ex2,
6475 : "change_ids should all be equal");
6476 0 : torture_assert_int_equal(tctx, change_id_ex2, change_id_info2,
6477 : "change_ids should all be equal");
6478 :
6479 0 : torture_assert(tctx, (change_id < change_id2),
6480 : talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
6481 : change_id2, change_id));
6482 0 : torture_assert(tctx, (change_id_ex < change_id_ex2),
6483 : talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
6484 : change_id_ex2, change_id_ex));
6485 0 : torture_assert(tctx, (change_id_info < change_id_info2),
6486 : talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
6487 : change_id_info2, change_id_info));
6488 :
6489 0 : torture_comment(tctx, "ChangeID tests succeeded\n\n");
6490 :
6491 0 : return true;
6492 : }
6493 :
6494 0 : static bool test_SecondaryClosePrinter(struct torture_context *tctx,
6495 : struct dcerpc_pipe *p,
6496 : struct policy_handle *handle)
6497 : {
6498 : NTSTATUS status;
6499 : struct cli_credentials *anon_creds;
6500 : const struct dcerpc_binding *binding2;
6501 : struct dcerpc_pipe *p2;
6502 : struct spoolss_ClosePrinter cp;
6503 :
6504 : /* only makes sense on SMB */
6505 0 : if (p->conn->transport.transport != NCACN_NP) {
6506 0 : return true;
6507 : }
6508 :
6509 0 : torture_comment(tctx, "Testing close on secondary pipe\n");
6510 :
6511 0 : anon_creds = cli_credentials_init_anon(tctx);
6512 0 : torture_assert(tctx, anon_creds != NULL, "cli_credentials_init_anon failed");
6513 :
6514 0 : binding2 = p->binding;
6515 0 : status = dcerpc_secondary_auth_connection(p, binding2, &ndr_table_spoolss,
6516 : anon_creds, tctx->lp_ctx,
6517 : tctx, &p2);
6518 0 : torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
6519 :
6520 0 : cp.in.handle = handle;
6521 0 : cp.out.handle = handle;
6522 :
6523 0 : status = dcerpc_spoolss_ClosePrinter_r(p2->binding_handle, tctx, &cp);
6524 0 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH,
6525 : "ERROR: Allowed close on secondary connection");
6526 :
6527 0 : talloc_free(p2);
6528 :
6529 0 : return true;
6530 : }
6531 :
6532 0 : static bool test_OpenPrinter_badname(struct torture_context *tctx,
6533 : struct dcerpc_binding_handle *b, const char *name)
6534 : {
6535 : NTSTATUS status;
6536 : struct spoolss_OpenPrinter op;
6537 : struct spoolss_OpenPrinterEx opEx;
6538 : struct policy_handle handle;
6539 0 : bool ret = true;
6540 :
6541 0 : op.in.printername = name;
6542 0 : op.in.datatype = NULL;
6543 0 : op.in.devmode_ctr.devmode= NULL;
6544 0 : op.in.access_mask = 0;
6545 0 : op.out.handle = &handle;
6546 :
6547 0 : torture_comment(tctx, "Testing OpenPrinter(%s) with bad name\n", op.in.printername);
6548 :
6549 0 : status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &op);
6550 0 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
6551 0 : torture_assert_werr_equal(tctx, op.out.result, WERR_INVALID_PRINTER_NAME,
6552 : "unexpected result");
6553 :
6554 0 : if (W_ERROR_IS_OK(op.out.result)) {
6555 0 : ret &=test_ClosePrinter(tctx, b, &handle);
6556 : }
6557 :
6558 0 : opEx.in.printername = name;
6559 0 : opEx.in.datatype = NULL;
6560 0 : opEx.in.devmode_ctr.devmode = NULL;
6561 0 : opEx.in.access_mask = 0;
6562 0 : opEx.in.userlevel_ctr.level = 1;
6563 0 : opEx.in.userlevel_ctr.user_info.level1 = NULL;
6564 0 : opEx.out.handle = &handle;
6565 :
6566 0 : torture_comment(tctx, "Testing OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
6567 :
6568 0 : status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &opEx);
6569 0 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
6570 0 : torture_assert_werr_equal(tctx, opEx.out.result, WERR_INVALID_PARAMETER,
6571 : "unexpected result");
6572 :
6573 0 : if (W_ERROR_IS_OK(opEx.out.result)) {
6574 0 : ret &=test_ClosePrinter(tctx, b, &handle);
6575 : }
6576 :
6577 0 : return ret;
6578 : }
6579 :
6580 0 : static bool test_OpenPrinter_badname_list(struct torture_context *tctx,
6581 : void *private_data)
6582 : {
6583 0 : struct test_spoolss_context *ctx =
6584 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
6585 :
6586 0 : const char *badnames[] = {
6587 : "__INVALID_PRINTER__",
6588 : "\\\\__INVALID_HOST__",
6589 : "",
6590 : "\\\\\\",
6591 : "\\\\\\__INVALID_PRINTER__"
6592 : };
6593 : const char *badname;
6594 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
6595 0 : const char *server_name = dcerpc_server_name(p);
6596 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6597 : int i;
6598 :
6599 0 : for (i=0; i < ARRAY_SIZE(badnames); i++) {
6600 0 : torture_assert(tctx,
6601 : test_OpenPrinter_badname(tctx, b, badnames[i]),
6602 : "");
6603 : }
6604 :
6605 0 : badname = talloc_asprintf(tctx, "\\\\%s\\", server_name);
6606 0 : torture_assert(tctx,
6607 : test_OpenPrinter_badname(tctx, b, badname),
6608 : "");
6609 :
6610 0 : badname = talloc_asprintf(tctx, "\\\\%s\\__INVALID_PRINTER__", server_name);
6611 0 : torture_assert(tctx,
6612 : test_OpenPrinter_badname(tctx, b, badname),
6613 : "");
6614 :
6615 0 : return true;
6616 : }
6617 :
6618 0 : static bool test_OpenPrinter(struct torture_context *tctx,
6619 : struct dcerpc_pipe *p,
6620 : const char *name,
6621 : const char *environment,
6622 : bool open_only)
6623 : {
6624 : NTSTATUS status;
6625 : struct spoolss_OpenPrinter r;
6626 : struct policy_handle handle;
6627 0 : bool ret = true;
6628 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6629 :
6630 0 : r.in.printername = name;
6631 0 : r.in.datatype = NULL;
6632 0 : r.in.devmode_ctr.devmode= NULL;
6633 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
6634 0 : r.out.handle = &handle;
6635 :
6636 0 : torture_comment(tctx, "Testing OpenPrinter(%s)\n", r.in.printername);
6637 :
6638 0 : status = dcerpc_spoolss_OpenPrinter_r(b, tctx, &r);
6639 :
6640 0 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
6641 :
6642 0 : torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed");
6643 :
6644 0 : if (open_only) {
6645 0 : goto close_printer;
6646 : }
6647 :
6648 0 : if (!test_GetPrinter(tctx, b, &handle, environment)) {
6649 0 : ret = false;
6650 : }
6651 :
6652 0 : if (!torture_setting_bool(tctx, "samba3", false)) {
6653 0 : if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
6654 0 : ret = false;
6655 : }
6656 : }
6657 :
6658 0 : close_printer:
6659 0 : if (!test_ClosePrinter(tctx, b, &handle)) {
6660 0 : ret = false;
6661 : }
6662 :
6663 0 : return ret;
6664 : }
6665 :
6666 0 : static bool test_OpenPrinterEx(struct torture_context *tctx,
6667 : struct dcerpc_binding_handle *b,
6668 : const char *printername,
6669 : const char *datatype,
6670 : struct spoolss_DeviceMode *devmode,
6671 : uint32_t access_mask,
6672 : struct spoolss_UserLevelCtr *userlevel_ctr,
6673 : struct policy_handle *handle,
6674 : WERROR expected_result)
6675 : {
6676 : struct spoolss_OpenPrinterEx r;
6677 :
6678 0 : r.in.printername = printername;
6679 0 : r.in.datatype = datatype;
6680 0 : r.in.devmode_ctr.devmode= devmode;
6681 0 : r.in.access_mask = access_mask;
6682 0 : r.in.userlevel_ctr = *userlevel_ctr;
6683 0 : r.out.handle = handle;
6684 :
6685 0 : torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername);
6686 :
6687 0 : torture_assert_ntstatus_ok(tctx,
6688 : dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r),
6689 : "OpenPrinterEx failed");
6690 :
6691 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
6692 : "OpenPrinterEx failed");
6693 :
6694 0 : return true;
6695 : }
6696 :
6697 0 : static bool call_OpenPrinterEx(struct torture_context *tctx,
6698 : struct dcerpc_pipe *p,
6699 : const char *name,
6700 : struct spoolss_DeviceMode *devmode,
6701 : struct policy_handle *handle)
6702 : {
6703 : struct spoolss_UserLevelCtr userlevel_ctr;
6704 : struct spoolss_UserLevel1 userlevel1;
6705 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6706 :
6707 0 : userlevel1.size = 1234;
6708 0 : userlevel1.client = "hello";
6709 0 : userlevel1.user = "spottyfoot!";
6710 0 : userlevel1.build = 1;
6711 0 : userlevel1.major = 2;
6712 0 : userlevel1.minor = 3;
6713 0 : userlevel1.processor = 4;
6714 :
6715 0 : userlevel_ctr.level = 1;
6716 0 : userlevel_ctr.user_info.level1 = &userlevel1;
6717 :
6718 0 : return test_OpenPrinterEx(tctx, b, name, NULL, devmode,
6719 : SEC_FLAG_MAXIMUM_ALLOWED,
6720 : &userlevel_ctr,
6721 : handle,
6722 0 : WERR_OK);
6723 : }
6724 :
6725 0 : static bool test_printer_rename(struct torture_context *tctx,
6726 : void *private_data)
6727 : {
6728 0 : struct torture_printer_context *t =
6729 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
6730 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
6731 :
6732 0 : bool ret = true;
6733 : union spoolss_PrinterInfo info;
6734 : union spoolss_SetPrinterInfo sinfo;
6735 : struct spoolss_SetPrinterInfoCtr info_ctr;
6736 : struct spoolss_DevmodeContainer devmode_ctr;
6737 : struct sec_desc_buf secdesc_ctr;
6738 : const char *printer_name;
6739 : const char *printer_name_orig;
6740 0 : const char *printer_name_new = "SAMBA smbtorture Test Printer (Copy 2)";
6741 : struct policy_handle new_handle;
6742 : const char *q;
6743 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6744 :
6745 0 : ZERO_STRUCT(devmode_ctr);
6746 0 : ZERO_STRUCT(secdesc_ctr);
6747 :
6748 0 : torture_comment(tctx, "Testing Printer rename operations\n");
6749 :
6750 0 : torture_assert(tctx,
6751 : test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
6752 : "failed to call GetPrinter level 2");
6753 :
6754 0 : printer_name_orig = talloc_strdup(tctx, info.info2.printername);
6755 :
6756 0 : q = strrchr(info.info2.printername, '\\');
6757 0 : if (q) {
6758 0 : torture_warning(tctx,
6759 : "server returns printername %s incl. servername although we did not set servername", info.info2.printername);
6760 : }
6761 :
6762 0 : torture_assert(tctx,
6763 : PrinterInfo_to_SetPrinterInfo(tctx, &info, 2, &sinfo), "");
6764 :
6765 0 : sinfo.info2->printername = printer_name_new;
6766 :
6767 0 : info_ctr.level = 2;
6768 0 : info_ctr.info = sinfo;
6769 :
6770 0 : torture_assert(tctx,
6771 : test_SetPrinter(tctx, b, &t->handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
6772 : "failed to call SetPrinter level 2");
6773 :
6774 0 : torture_assert(tctx,
6775 : test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
6776 : "failed to call GetPrinter level 2");
6777 :
6778 0 : printer_name = talloc_strdup(tctx, info.info2.printername);
6779 :
6780 0 : q = strrchr(info.info2.printername, '\\');
6781 0 : if (q) {
6782 0 : torture_warning(tctx,
6783 : "server returns printername %s incl. servername although we did not set servername", info.info2.printername);
6784 0 : q++;
6785 0 : printer_name = q;
6786 : }
6787 :
6788 0 : torture_assert_str_equal(tctx, printer_name, printer_name_new,
6789 : "new printer name was not set");
6790 :
6791 : /* samba currently cannot fully rename printers */
6792 0 : if (!torture_setting_bool(tctx, "samba3", false)) {
6793 0 : torture_assert(tctx,
6794 : test_OpenPrinter_badname(tctx, b, printer_name_orig),
6795 : "still can open printer with oldname after rename");
6796 : } else {
6797 0 : torture_warning(tctx, "*not* checking for open with oldname after rename for samba3");
6798 : }
6799 :
6800 0 : torture_assert(tctx,
6801 : call_OpenPrinterEx(tctx, p, printer_name_new, NULL, &new_handle),
6802 : "failed to open printer with new name");
6803 :
6804 0 : torture_assert(tctx,
6805 : test_GetPrinter_level(tctx, b, &new_handle, 2, &info),
6806 : "failed to call GetPrinter level 2");
6807 :
6808 0 : torture_assert_str_equal(tctx, info.info2.printername, printer_name_new,
6809 : "new printer name was not set");
6810 :
6811 0 : torture_assert(tctx,
6812 : test_ClosePrinter(tctx, b, &new_handle),
6813 : "failed to close printer");
6814 :
6815 0 : torture_comment(tctx, "Printer rename operations test succeeded\n\n");
6816 :
6817 0 : return ret;
6818 : }
6819 :
6820 0 : static bool test_openprinter(struct torture_context *tctx,
6821 : struct dcerpc_binding_handle *b,
6822 : const char *real_printername)
6823 : {
6824 : struct spoolss_UserLevelCtr userlevel_ctr;
6825 : struct policy_handle handle;
6826 : struct spoolss_UserLevel1 userlevel1;
6827 0 : const char *printername = NULL;
6828 : int i;
6829 :
6830 : struct {
6831 : const char *suffix;
6832 : WERROR expected_result;
6833 0 : } tests[] = {
6834 : {
6835 : .suffix = "rubbish",
6836 : .expected_result = WERR_INVALID_PRINTER_NAME
6837 : },{
6838 : .suffix = ", LocalOnl",
6839 : .expected_result = WERR_INVALID_PRINTER_NAME
6840 : },{
6841 : .suffix = ", localOnly",
6842 : .expected_result = WERR_INVALID_PRINTER_NAME
6843 : },{
6844 : .suffix = ", localonl",
6845 : .expected_result = WERR_INVALID_PRINTER_NAME
6846 : },{
6847 : .suffix = ",LocalOnl",
6848 : .expected_result = WERR_INVALID_PRINTER_NAME
6849 : },{
6850 : .suffix = ",localOnl2",
6851 : .expected_result = WERR_INVALID_PRINTER_NAME
6852 : },{
6853 : .suffix = ", DrvConver2t",
6854 : .expected_result = WERR_INVALID_PRINTER_NAME
6855 : },{
6856 : .suffix = ", drvconvert",
6857 : .expected_result = WERR_INVALID_PRINTER_NAME
6858 : },{
6859 : .suffix = ",drvconvert",
6860 : .expected_result = WERR_INVALID_PRINTER_NAME
6861 : },{
6862 : .suffix = ", DrvConvert",
6863 : .expected_result = WERR_OK
6864 : },{
6865 : .suffix = " , DrvConvert",
6866 : .expected_result = WERR_INVALID_PRINTER_NAME
6867 : },{
6868 : .suffix = ",DrvConvert",
6869 : .expected_result = WERR_OK
6870 : },{
6871 : .suffix = ", DrvConvertsadfasdf",
6872 : .expected_result = WERR_OK
6873 : },{
6874 : .suffix = ",DrvConvertasdfasd",
6875 : .expected_result = WERR_OK
6876 : },{
6877 : .suffix = ", LocalOnly",
6878 : .expected_result = WERR_OK
6879 : },{
6880 : .suffix = " , LocalOnly",
6881 : .expected_result = WERR_INVALID_PRINTER_NAME
6882 : },{
6883 : .suffix = ",LocalOnly",
6884 : .expected_result = WERR_OK
6885 : },{
6886 : .suffix = ", LocalOnlysagi4gjfkd",
6887 : .expected_result = WERR_OK
6888 : },{
6889 : .suffix = ",LocalOnlysagi4gjfkd",
6890 : .expected_result = WERR_OK
6891 : }
6892 : };
6893 :
6894 0 : userlevel1.size = 1234;
6895 0 : userlevel1.client = "hello";
6896 0 : userlevel1.user = "spottyfoot!";
6897 0 : userlevel1.build = 1;
6898 0 : userlevel1.major = 2;
6899 0 : userlevel1.minor = 3;
6900 0 : userlevel1.processor = 4;
6901 :
6902 0 : userlevel_ctr.level = 1;
6903 0 : userlevel_ctr.user_info.level1 = &userlevel1;
6904 :
6905 0 : torture_comment(tctx, "Testing openprinterex printername pattern\n");
6906 :
6907 0 : torture_assert(tctx,
6908 : test_OpenPrinterEx(tctx, b, real_printername, NULL, NULL, 0,
6909 : &userlevel_ctr, &handle,
6910 : WERR_OK),
6911 : "OpenPrinterEx failed");
6912 0 : test_ClosePrinter(tctx, b, &handle);
6913 :
6914 0 : for (i=0; i < ARRAY_SIZE(tests); i++) {
6915 :
6916 0 : printername = talloc_asprintf(tctx, "%s%s",
6917 : real_printername,
6918 : tests[i].suffix);
6919 :
6920 0 : torture_assert(tctx,
6921 : test_OpenPrinterEx(tctx, b, printername, NULL, NULL, 0,
6922 : &userlevel_ctr, &handle,
6923 : tests[i].expected_result),
6924 : "OpenPrinterEx failed");
6925 0 : if (W_ERROR_IS_OK(tests[i].expected_result)) {
6926 0 : test_ClosePrinter(tctx, b, &handle);
6927 : }
6928 : }
6929 :
6930 0 : return true;
6931 : }
6932 :
6933 :
6934 0 : static bool test_existing_printer_openprinterex(struct torture_context *tctx,
6935 : struct dcerpc_pipe *p,
6936 : const char *name,
6937 : const char *environment)
6938 : {
6939 : struct policy_handle handle;
6940 0 : bool ret = true;
6941 0 : struct dcerpc_binding_handle *b = p->binding_handle;
6942 :
6943 0 : if (!test_openprinter(tctx, b, name)) {
6944 0 : return false;
6945 : }
6946 :
6947 0 : if (!call_OpenPrinterEx(tctx, p, name, NULL, &handle)) {
6948 0 : return false;
6949 : }
6950 :
6951 0 : if (!test_PrinterInfo_SD(tctx, b, &handle)) {
6952 0 : ret = false;
6953 : }
6954 :
6955 0 : if (!test_GetPrinter(tctx, b, &handle, environment)) {
6956 0 : ret = false;
6957 : }
6958 :
6959 0 : if (!test_EnumForms_all(tctx, b, &handle, false)) {
6960 0 : ret = false;
6961 : }
6962 :
6963 0 : if (!test_Forms(tctx, b, &handle, false, name, NULL, NULL)) {
6964 0 : ret = false;
6965 : }
6966 :
6967 0 : if (!test_Forms_winreg(tctx, b, &handle, false, name)) {
6968 0 : ret = false;
6969 : }
6970 :
6971 0 : if (!test_EnumPrinterData_all(tctx, p, &handle)) {
6972 0 : ret = false;
6973 : }
6974 :
6975 0 : if (!test_EnumPrinterDataEx(tctx, b, &handle, "PrinterDriverData", NULL, NULL)) {
6976 0 : ret = false;
6977 : }
6978 :
6979 0 : if (!test_EnumPrinterData_consistency(tctx, p, &handle)) {
6980 0 : ret = false;
6981 : }
6982 :
6983 0 : if (!test_printer_all_keys(tctx, b, &handle)) {
6984 0 : ret = false;
6985 : }
6986 :
6987 0 : if (!test_PausePrinter(tctx, b, &handle)) {
6988 0 : ret = false;
6989 : }
6990 :
6991 0 : if (!test_DoPrintTest(tctx, b, &handle)) {
6992 0 : ret = false;
6993 : }
6994 :
6995 0 : if (!test_ResumePrinter(tctx, b, &handle)) {
6996 0 : ret = false;
6997 : }
6998 :
6999 0 : if (!test_SetPrinterData_matrix(tctx, b, &handle, name, NULL, NULL)) {
7000 0 : ret = false;
7001 : }
7002 :
7003 0 : if (!test_SetPrinterDataEx_matrix(tctx, p, &handle, name, NULL, NULL)) {
7004 0 : ret = false;
7005 : }
7006 :
7007 0 : if (!torture_setting_bool(tctx, "samba3", false)) {
7008 0 : if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
7009 0 : ret = false;
7010 : }
7011 : }
7012 :
7013 0 : if (!test_ClosePrinter(tctx, b, &handle)) {
7014 0 : ret = false;
7015 : }
7016 :
7017 0 : return ret;
7018 : }
7019 :
7020 0 : static bool test_EnumPrinters_old(struct torture_context *tctx,
7021 : void *private_data)
7022 : {
7023 0 : struct test_spoolss_context *ctx =
7024 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
7025 : struct spoolss_EnumPrinters r;
7026 : NTSTATUS status;
7027 0 : uint16_t levels[] = {1, 2, 4, 5};
7028 : int i;
7029 0 : bool ret = true;
7030 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
7031 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7032 :
7033 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
7034 : union spoolss_PrinterInfo *info;
7035 : int j;
7036 : uint32_t needed;
7037 : uint32_t count;
7038 :
7039 0 : r.in.flags = PRINTER_ENUM_LOCAL;
7040 0 : r.in.server = "";
7041 0 : r.in.level = levels[i];
7042 0 : r.in.buffer = NULL;
7043 0 : r.in.offered = 0;
7044 0 : r.out.needed = &needed;
7045 0 : r.out.count = &count;
7046 0 : r.out.info = &info;
7047 :
7048 0 : torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
7049 :
7050 0 : status = dcerpc_spoolss_EnumPrinters_r(b, tctx, &r);
7051 0 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
7052 :
7053 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7054 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7055 0 : r.in.buffer = &blob;
7056 0 : r.in.offered = needed;
7057 0 : status = dcerpc_spoolss_EnumPrinters_r(b, tctx, &r);
7058 : }
7059 :
7060 0 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed");
7061 :
7062 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
7063 :
7064 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
7065 :
7066 0 : if (!info) {
7067 0 : torture_comment(tctx, "No printers returned\n");
7068 0 : return true;
7069 : }
7070 :
7071 0 : for (j=0;j<count;j++) {
7072 0 : if (r.in.level == 1) {
7073 0 : char *unc = talloc_strdup(tctx, info[j].info1.name);
7074 : char *slash, *name, *full_name;
7075 0 : name = unc;
7076 0 : if (unc[0] == '\\' && unc[1] == '\\') {
7077 0 : unc +=2;
7078 : }
7079 0 : slash = strchr(unc, '\\');
7080 0 : if (slash) {
7081 0 : slash++;
7082 0 : name = slash;
7083 : }
7084 0 : full_name = talloc_asprintf(tctx, "\\\\%s\\%s",
7085 : dcerpc_server_name(p), name);
7086 0 : if (!test_OpenPrinter(tctx, p, name, ctx->environment, true)) {
7087 0 : ret = false;
7088 : }
7089 0 : if (!test_OpenPrinter(tctx, p, full_name, ctx->environment, true)) {
7090 0 : ret = false;
7091 : }
7092 0 : if (!test_OpenPrinter(tctx, p, name, ctx->environment, false)) {
7093 0 : ret = false;
7094 : }
7095 0 : if (!test_existing_printer_openprinterex(tctx, p, name, ctx->environment)) {
7096 0 : ret = false;
7097 : }
7098 : }
7099 : }
7100 : }
7101 :
7102 0 : return ret;
7103 : }
7104 :
7105 0 : static bool test_EnumPrinters_level(struct torture_context *tctx,
7106 : struct dcerpc_binding_handle *b,
7107 : uint32_t flags,
7108 : const char *servername,
7109 : uint32_t level,
7110 : uint32_t *count_p,
7111 : union spoolss_PrinterInfo **info_p)
7112 : {
7113 : struct spoolss_EnumPrinters r;
7114 : union spoolss_PrinterInfo *info;
7115 : uint32_t needed;
7116 : uint32_t count;
7117 :
7118 0 : r.in.flags = flags;
7119 0 : r.in.server = servername;
7120 0 : r.in.level = level;
7121 0 : r.in.buffer = NULL;
7122 0 : r.in.offered = 0;
7123 0 : r.out.needed = &needed;
7124 0 : r.out.count = &count;
7125 0 : r.out.info = &info;
7126 :
7127 0 : torture_comment(tctx, "Testing EnumPrinters(%s) level %u\n",
7128 : r.in.server, r.in.level);
7129 :
7130 0 : torture_assert_ntstatus_ok(tctx,
7131 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
7132 : "EnumPrinters failed");
7133 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7134 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7135 0 : r.in.buffer = &blob;
7136 0 : r.in.offered = needed;
7137 0 : torture_assert_ntstatus_ok(tctx,
7138 : dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
7139 : "EnumPrinters failed");
7140 : }
7141 :
7142 0 : torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
7143 :
7144 0 : CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
7145 :
7146 0 : if (count_p) {
7147 0 : *count_p = count;
7148 : }
7149 0 : if (info_p) {
7150 0 : *info_p = info;
7151 : }
7152 :
7153 0 : return true;
7154 : }
7155 :
7156 0 : static const char *get_short_printername(struct torture_context *tctx,
7157 : const char *name)
7158 : {
7159 : const char *short_name;
7160 :
7161 0 : if (name[0] == '\\' && name[1] == '\\') {
7162 0 : name += 2;
7163 0 : short_name = strchr(name, '\\');
7164 0 : if (short_name) {
7165 0 : return talloc_strdup(tctx, short_name+1);
7166 : }
7167 : }
7168 :
7169 0 : return name;
7170 : }
7171 :
7172 0 : static const char *get_full_printername(struct torture_context *tctx,
7173 : const char *name)
7174 : {
7175 0 : const char *full_name = talloc_strdup(tctx, name);
7176 : char *p;
7177 :
7178 0 : if (name && name[0] == '\\' && name[1] == '\\') {
7179 0 : name += 2;
7180 0 : p = strchr(name, '\\');
7181 0 : if (p) {
7182 0 : return full_name;
7183 : }
7184 : }
7185 :
7186 0 : return NULL;
7187 : }
7188 :
7189 0 : static bool test_OnePrinter_servername(struct torture_context *tctx,
7190 : struct dcerpc_pipe *p,
7191 : struct dcerpc_binding_handle *b,
7192 : const char *servername,
7193 : const char *printername)
7194 : {
7195 : union spoolss_PrinterInfo info;
7196 0 : const char *short_name = get_short_printername(tctx, printername);
7197 0 : const char *full_name = get_full_printername(tctx, printername);
7198 :
7199 0 : if (short_name) {
7200 : struct policy_handle handle;
7201 0 : torture_assert(tctx,
7202 : call_OpenPrinterEx(tctx, p, short_name, NULL, &handle),
7203 : "failed to open printer");
7204 :
7205 0 : torture_assert(tctx,
7206 : test_GetPrinter_level(tctx, b, &handle, 2, &info),
7207 : "failed to get printer info");
7208 :
7209 0 : torture_assert_casestr_equal(tctx, info.info2.servername, NULL,
7210 : "unexpected servername");
7211 0 : torture_assert_casestr_equal(tctx, info.info2.printername, short_name,
7212 : "unexpected printername");
7213 :
7214 0 : if (info.info2.devmode) {
7215 : const char *expected_devicename;
7216 0 : expected_devicename = talloc_strndup(tctx, short_name, MIN(strlen(short_name), 31));
7217 0 : torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
7218 : "unexpected devicemode devicename");
7219 : }
7220 :
7221 0 : torture_assert(tctx,
7222 : test_ClosePrinter(tctx, b, &handle),
7223 : "failed to close printer");
7224 : }
7225 :
7226 0 : if (full_name) {
7227 : struct policy_handle handle;
7228 :
7229 0 : torture_assert(tctx,
7230 : call_OpenPrinterEx(tctx, p, full_name, NULL, &handle),
7231 : "failed to open printer");
7232 :
7233 0 : torture_assert(tctx,
7234 : test_GetPrinter_level(tctx, b, &handle, 2, &info),
7235 : "failed to get printer info");
7236 :
7237 0 : torture_assert_casestr_equal(tctx, info.info2.servername, servername,
7238 : "unexpected servername");
7239 0 : torture_assert_casestr_equal(tctx, info.info2.printername, full_name,
7240 : "unexpected printername");
7241 :
7242 0 : if (info.info2.devmode) {
7243 : const char *expected_devicename;
7244 0 : expected_devicename = talloc_strndup(tctx, full_name, MIN(strlen(full_name), 31));
7245 0 : torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
7246 : "unexpected devicemode devicename");
7247 : }
7248 :
7249 0 : torture_assert(tctx,
7250 : test_ClosePrinter(tctx, b, &handle),
7251 : "failed to close printer");
7252 : }
7253 :
7254 0 : return true;
7255 : }
7256 :
7257 0 : static bool test_EnumPrinters_servername(struct torture_context *tctx,
7258 : void *private_data)
7259 : {
7260 0 : struct test_spoolss_context *ctx =
7261 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
7262 : int i;
7263 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
7264 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7265 : uint32_t count;
7266 : union spoolss_PrinterInfo *info;
7267 : const char *servername;
7268 0 : uint32_t flags = PRINTER_ENUM_NAME|PRINTER_ENUM_LOCAL;
7269 :
7270 0 : torture_comment(tctx, "Testing servername behaviour in EnumPrinters and GetPrinters\n");
7271 :
7272 0 : servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
7273 :
7274 0 : torture_assert(tctx,
7275 : test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
7276 : "failed to enumerate printers");
7277 :
7278 0 : for (i=0; i < count; i++) {
7279 :
7280 0 : torture_assert_casestr_equal(tctx, info[i].info2.servername, servername,
7281 : "unexpected servername");
7282 :
7283 0 : torture_assert(tctx,
7284 : test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
7285 : "failed to check printer");
7286 : }
7287 :
7288 0 : servername = "";
7289 :
7290 0 : torture_assert(tctx,
7291 : test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
7292 : "failed to enumerate printers");
7293 :
7294 0 : for (i=0; i < count; i++) {
7295 :
7296 0 : torture_assert_casestr_equal(tctx, info[i].info2.servername, NULL,
7297 : "unexpected servername");
7298 :
7299 0 : torture_assert(tctx,
7300 : test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
7301 : "failed to check printer");
7302 : }
7303 :
7304 :
7305 0 : return true;
7306 : }
7307 :
7308 : #if 0
7309 : static bool test_GetPrinterDriver(struct torture_context *tctx,
7310 : struct dcerpc_binding_handle *b,
7311 : struct policy_handle *handle,
7312 : const char *driver_name)
7313 : {
7314 : struct spoolss_GetPrinterDriver r;
7315 : uint32_t needed;
7316 :
7317 : r.in.handle = handle;
7318 : r.in.architecture = "W32X86";
7319 : r.in.level = 1;
7320 : r.in.buffer = NULL;
7321 : r.in.offered = 0;
7322 : r.out.needed = &needed;
7323 :
7324 : torture_comment(tctx, "Testing GetPrinterDriver level %d\n", r.in.level);
7325 :
7326 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver_r(b, tctx, &r),
7327 : "failed to call GetPrinterDriver");
7328 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7329 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7330 : r.in.buffer = &blob;
7331 : r.in.offered = needed;
7332 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver_r(b, tctx, &r),
7333 : "failed to call GetPrinterDriver");
7334 : }
7335 :
7336 : torture_assert_werr_ok(tctx, r.out.result,
7337 : "failed to call GetPrinterDriver");
7338 :
7339 : CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
7340 :
7341 : return true;
7342 : }
7343 : #endif
7344 :
7345 0 : static bool test_GetPrinterDriver2_level(struct torture_context *tctx,
7346 : struct dcerpc_binding_handle *b,
7347 : struct policy_handle *handle,
7348 : const char *driver_name,
7349 : const char *architecture,
7350 : uint32_t level,
7351 : uint32_t client_major_version,
7352 : uint32_t client_minor_version,
7353 : union spoolss_DriverInfo *info_p,
7354 : WERROR *result_p)
7355 :
7356 : {
7357 : struct spoolss_GetPrinterDriver2 r;
7358 : uint32_t needed;
7359 : uint32_t server_major_version;
7360 : uint32_t server_minor_version;
7361 :
7362 0 : r.in.handle = handle;
7363 0 : r.in.architecture = architecture;
7364 0 : r.in.client_major_version = client_major_version;
7365 0 : r.in.client_minor_version = client_minor_version;
7366 0 : r.in.buffer = NULL;
7367 0 : r.in.offered = 0;
7368 0 : r.in.level = level;
7369 0 : r.out.needed = &needed;
7370 0 : r.out.server_major_version = &server_major_version;
7371 0 : r.out.server_minor_version = &server_minor_version;
7372 :
7373 0 : torture_comment(tctx, "Testing GetPrinterDriver2(%s) level %d\n",
7374 : driver_name, r.in.level);
7375 :
7376 0 : torture_assert_ntstatus_ok(tctx,
7377 : dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &r),
7378 : "failed to call GetPrinterDriver2");
7379 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
7380 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7381 0 : r.in.buffer = &blob;
7382 0 : r.in.offered = needed;
7383 0 : torture_assert_ntstatus_ok(tctx,
7384 : dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &r),
7385 : "failed to call GetPrinterDriver2");
7386 : }
7387 :
7388 0 : if (result_p) {
7389 0 : *result_p = r.out.result;
7390 : }
7391 :
7392 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INVALID_LEVEL)) {
7393 0 : switch (r.in.level) {
7394 0 : case 101:
7395 : case 8:
7396 0 : torture_comment(tctx,
7397 : "level %d not implemented, not considering as an error\n",
7398 : r.in.level);
7399 0 : return true;
7400 0 : default:
7401 0 : break;
7402 : }
7403 0 : }
7404 :
7405 0 : torture_assert_werr_ok(tctx, r.out.result,
7406 : "failed to call GetPrinterDriver2");
7407 :
7408 0 : CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
7409 :
7410 0 : if (info_p) {
7411 0 : *info_p = *r.out.info;
7412 : }
7413 :
7414 0 : return true;
7415 : }
7416 :
7417 0 : static bool test_GetPrinterDriver2(struct torture_context *tctx,
7418 : struct dcerpc_binding_handle *b,
7419 : struct policy_handle *handle,
7420 : const char *driver_name,
7421 : const char *architecture)
7422 : {
7423 0 : uint16_t levels[] = {1, 2, 3, 4, 5, 6, 8, 101 };
7424 : int i;
7425 :
7426 :
7427 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
7428 :
7429 0 : torture_assert(tctx,
7430 : test_GetPrinterDriver2_level(tctx, b, handle, driver_name, architecture, levels[i], 3, 0, NULL, NULL),
7431 : "");
7432 : }
7433 :
7434 0 : return true;
7435 : }
7436 :
7437 0 : static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
7438 : void *private_data)
7439 : {
7440 0 : struct test_spoolss_context *ctx =
7441 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
7442 0 : uint16_t levels[] = {1, 2, 3, 4, 5, 6};
7443 : int i;
7444 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
7445 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7446 0 : const char *server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
7447 :
7448 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
7449 :
7450 : uint32_t count;
7451 : union spoolss_DriverInfo *info;
7452 :
7453 0 : torture_assert(tctx,
7454 : test_EnumPrinterDrivers_args(tctx, b, server_name, ctx->environment, levels[i], &count, &info),
7455 : "failed to enumerate drivers");
7456 :
7457 0 : if (!info) {
7458 0 : torture_comment(tctx, "No printer drivers returned\n");
7459 0 : break;
7460 : }
7461 : }
7462 :
7463 0 : return true;
7464 : }
7465 :
7466 0 : static bool test_DeletePrinter(struct torture_context *tctx,
7467 : struct dcerpc_binding_handle *b,
7468 : struct policy_handle *handle)
7469 : {
7470 : struct spoolss_DeletePrinter r;
7471 :
7472 0 : torture_comment(tctx, "Testing DeletePrinter\n");
7473 :
7474 0 : r.in.handle = handle;
7475 :
7476 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter_r(b, tctx, &r),
7477 : "failed to delete printer");
7478 0 : torture_assert_werr_ok(tctx, r.out.result,
7479 : "failed to delete printer");
7480 :
7481 0 : return true;
7482 : }
7483 :
7484 0 : static bool test_EnumPrinters_findname(struct torture_context *tctx,
7485 : struct dcerpc_binding_handle *b,
7486 : uint32_t flags,
7487 : uint32_t level,
7488 : const char *name,
7489 : bool *found)
7490 : {
7491 : struct spoolss_EnumPrinters e;
7492 : uint32_t count;
7493 : union spoolss_PrinterInfo *info;
7494 : uint32_t needed;
7495 : int i;
7496 :
7497 0 : *found = false;
7498 :
7499 0 : e.in.flags = flags;
7500 0 : e.in.server = NULL;
7501 0 : e.in.level = level;
7502 0 : e.in.buffer = NULL;
7503 0 : e.in.offered = 0;
7504 0 : e.out.count = &count;
7505 0 : e.out.info = &info;
7506 0 : e.out.needed = &needed;
7507 :
7508 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e),
7509 : "failed to enum printers");
7510 :
7511 0 : if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) {
7512 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
7513 0 : e.in.buffer = &blob;
7514 0 : e.in.offered = needed;
7515 :
7516 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e),
7517 : "failed to enum printers");
7518 : }
7519 :
7520 0 : torture_assert_werr_ok(tctx, e.out.result,
7521 : "failed to enum printers");
7522 :
7523 0 : for (i=0; i < count; i++) {
7524 :
7525 0 : const char *current = NULL;
7526 : const char *q;
7527 :
7528 0 : switch (level) {
7529 0 : case 1:
7530 0 : current = info[i].info1.name;
7531 0 : break;
7532 : }
7533 :
7534 0 : if (strequal(current, name)) {
7535 0 : *found = true;
7536 0 : break;
7537 : }
7538 :
7539 0 : q = strrchr(current, '\\');
7540 0 : if (q) {
7541 0 : if (!e.in.server) {
7542 0 : torture_warning(tctx,
7543 : "server returns printername %s incl. servername although we did not set servername", current);
7544 : }
7545 0 : q++;
7546 0 : if (strequal(q, name)) {
7547 0 : *found = true;
7548 0 : break;
7549 : }
7550 : }
7551 : }
7552 :
7553 0 : return true;
7554 : }
7555 :
7556 0 : static bool test_AddPrinter_wellknown(struct torture_context *tctx,
7557 : struct dcerpc_pipe *p,
7558 : const char *printername,
7559 : bool ex)
7560 : {
7561 : WERROR result;
7562 : struct spoolss_AddPrinter r;
7563 : struct spoolss_AddPrinterEx rex;
7564 : struct spoolss_SetPrinterInfoCtr info_ctr;
7565 : struct spoolss_SetPrinterInfo1 info1;
7566 : struct spoolss_DevmodeContainer devmode_ctr;
7567 : struct sec_desc_buf secdesc_ctr;
7568 : struct spoolss_UserLevelCtr userlevel_ctr;
7569 : struct policy_handle handle;
7570 0 : bool found = false;
7571 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7572 :
7573 0 : ZERO_STRUCT(devmode_ctr);
7574 0 : ZERO_STRUCT(secdesc_ctr);
7575 0 : ZERO_STRUCT(userlevel_ctr);
7576 0 : ZERO_STRUCT(info1);
7577 :
7578 0 : torture_comment(tctx, "Testing AddPrinter%s(%s) level 1\n",
7579 : ex ? "Ex":"", printername);
7580 :
7581 : /* try to add printer to wellknown printer list (level 1) */
7582 :
7583 0 : userlevel_ctr.level = 1;
7584 :
7585 0 : info_ctr.info.info1 = &info1;
7586 0 : info_ctr.level = 1;
7587 :
7588 0 : rex.in.server = NULL;
7589 0 : rex.in.info_ctr = &info_ctr;
7590 0 : rex.in.devmode_ctr = &devmode_ctr;
7591 0 : rex.in.secdesc_ctr = &secdesc_ctr;
7592 0 : rex.in.userlevel_ctr = &userlevel_ctr;
7593 0 : rex.out.handle = &handle;
7594 :
7595 0 : r.in.server = NULL;
7596 0 : r.in.info_ctr = &info_ctr;
7597 0 : r.in.devmode_ctr = &devmode_ctr;
7598 0 : r.in.secdesc_ctr = &secdesc_ctr;
7599 0 : r.out.handle = &handle;
7600 :
7601 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7602 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7603 : "failed to add printer");
7604 0 : result = ex ? rex.out.result : r.out.result;
7605 0 : torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
7606 : "unexpected result code");
7607 :
7608 0 : info1.name = printername;
7609 0 : info1.flags = PRINTER_ATTRIBUTE_SHARED;
7610 :
7611 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7612 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7613 : "failed to add printer");
7614 0 : result = ex ? rex.out.result : r.out.result;
7615 0 : torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
7616 : "unexpected result code");
7617 :
7618 : /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
7619 : better do a real check to see the printer is really there */
7620 :
7621 0 : torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
7622 : PRINTER_ENUM_NETWORK, 1,
7623 : printername,
7624 : &found),
7625 : "failed to enum printers");
7626 :
7627 0 : torture_assert(tctx, found, "failed to find newly added printer");
7628 :
7629 0 : info1.flags = 0;
7630 :
7631 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7632 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7633 : "failed to add printer");
7634 0 : result = ex ? rex.out.result : r.out.result;
7635 0 : torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
7636 : "unexpected result code");
7637 :
7638 : /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
7639 : better do a real check to see the printer has really been removed
7640 : from the well known printer list */
7641 :
7642 0 : found = false;
7643 :
7644 0 : torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
7645 : PRINTER_ENUM_NETWORK, 1,
7646 : printername,
7647 : &found),
7648 : "failed to enum printers");
7649 : #if 0
7650 : torture_assert(tctx, !found, "printer still in well known printer list");
7651 : #endif
7652 0 : return true;
7653 : }
7654 :
7655 0 : static bool test_AddPrinter_normal(struct torture_context *tctx,
7656 : struct dcerpc_pipe *p,
7657 : struct policy_handle *handle_p,
7658 : const char *printername,
7659 : const char *drivername,
7660 : const char *portname,
7661 : struct spoolss_DeviceMode *devmode,
7662 : bool ex)
7663 : {
7664 : WERROR result;
7665 : struct spoolss_AddPrinter r;
7666 : struct spoolss_AddPrinterEx rex;
7667 : struct spoolss_SetPrinterInfoCtr info_ctr;
7668 : struct spoolss_SetPrinterInfo2 info2;
7669 : struct spoolss_DevmodeContainer devmode_ctr;
7670 : struct sec_desc_buf secdesc_ctr;
7671 : struct spoolss_UserLevelCtr userlevel_ctr;
7672 : struct policy_handle handle;
7673 0 : bool found = false;
7674 0 : bool existing_printer_deleted = false;
7675 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7676 :
7677 0 : ZERO_STRUCT(devmode_ctr);
7678 0 : ZERO_STRUCT(secdesc_ctr);
7679 0 : ZERO_STRUCT(userlevel_ctr);
7680 :
7681 0 : torture_comment(tctx, "Testing AddPrinter%s(%s) level 2\n",
7682 : ex ? "Ex":"", printername);
7683 :
7684 0 : devmode_ctr.devmode = devmode;
7685 :
7686 0 : userlevel_ctr.level = 1;
7687 :
7688 0 : rex.in.server = NULL;
7689 0 : rex.in.info_ctr = &info_ctr;
7690 0 : rex.in.devmode_ctr = &devmode_ctr;
7691 0 : rex.in.secdesc_ctr = &secdesc_ctr;
7692 0 : rex.in.userlevel_ctr = &userlevel_ctr;
7693 0 : rex.out.handle = &handle;
7694 :
7695 0 : r.in.server = NULL;
7696 0 : r.in.info_ctr = &info_ctr;
7697 0 : r.in.devmode_ctr = &devmode_ctr;
7698 0 : r.in.secdesc_ctr = &secdesc_ctr;
7699 0 : r.out.handle = &handle;
7700 :
7701 0 : again:
7702 :
7703 : /* try to add printer to printer list (level 2) */
7704 :
7705 0 : ZERO_STRUCT(info2);
7706 :
7707 0 : info_ctr.info.info2 = &info2;
7708 0 : info_ctr.level = 2;
7709 :
7710 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7711 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7712 : "failed to add printer");
7713 0 : result = ex ? rex.out.result : r.out.result;
7714 0 : torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
7715 : "unexpected result code");
7716 :
7717 0 : info2.printername = printername;
7718 :
7719 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7720 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7721 : "failed to add printer");
7722 0 : result = ex ? rex.out.result : r.out.result;
7723 :
7724 0 : if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) {
7725 : struct policy_handle printer_handle;
7726 :
7727 0 : if (existing_printer_deleted) {
7728 0 : torture_fail(tctx, "already deleted printer still existing?");
7729 : }
7730 :
7731 0 : torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, NULL, &printer_handle),
7732 : "failed to open printer handle");
7733 :
7734 0 : torture_assert(tctx, test_DeletePrinter(tctx, b, &printer_handle),
7735 : "failed to delete printer");
7736 :
7737 0 : torture_assert(tctx, test_ClosePrinter(tctx, b, &printer_handle),
7738 : "failed to close server handle");
7739 :
7740 0 : existing_printer_deleted = true;
7741 :
7742 0 : goto again;
7743 : }
7744 :
7745 0 : torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT,
7746 : "unexpected result code");
7747 :
7748 0 : info2.portname = portname;
7749 :
7750 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7751 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7752 : "failed to add printer");
7753 0 : result = ex ? rex.out.result : r.out.result;
7754 0 : torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER,
7755 : "unexpected result code");
7756 :
7757 0 : info2.drivername = drivername;
7758 :
7759 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7760 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7761 : "failed to add printer");
7762 0 : result = ex ? rex.out.result : r.out.result;
7763 :
7764 : /* w2k8r2 allows one to add printer w/o defining printprocessor */
7765 :
7766 0 : if (!W_ERROR_IS_OK(result)) {
7767 0 : torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR,
7768 : "unexpected result code");
7769 :
7770 0 : info2.printprocessor = "winprint";
7771 :
7772 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7773 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7774 : "failed to add printer");
7775 0 : result = ex ? rex.out.result : r.out.result;
7776 0 : torture_assert_werr_ok(tctx, result,
7777 : "failed to add printer");
7778 : }
7779 :
7780 0 : *handle_p = handle;
7781 :
7782 : /* we are paranoid, really check if the printer is there now */
7783 :
7784 0 : torture_assert(tctx, test_EnumPrinters_findname(tctx, b,
7785 : PRINTER_ENUM_LOCAL, 1,
7786 : printername,
7787 : &found),
7788 : "failed to enum printers");
7789 0 : torture_assert(tctx, found, "failed to find newly added printer");
7790 :
7791 0 : torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx_r(b, tctx, &rex) :
7792 : dcerpc_spoolss_AddPrinter_r(b, tctx, &r),
7793 : "failed to add printer");
7794 0 : result = ex ? rex.out.result : r.out.result;
7795 0 : torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
7796 : "unexpected result code");
7797 :
7798 0 : return true;
7799 : }
7800 :
7801 0 : static bool test_printer_info(struct torture_context *tctx,
7802 : void *private_data)
7803 : {
7804 0 : struct torture_printer_context *t =
7805 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7806 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
7807 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7808 :
7809 0 : bool ret = true;
7810 :
7811 0 : if (torture_setting_bool(tctx, "samba3", false)) {
7812 0 : torture_skip(tctx, "skipping printer info cross tests against samba 3");
7813 : }
7814 :
7815 0 : if (!test_PrinterInfo(tctx, b, &t->handle)) {
7816 0 : ret = false;
7817 : }
7818 :
7819 0 : if (!test_SetPrinter_errors(tctx, b, &t->handle)) {
7820 0 : ret = false;
7821 : }
7822 :
7823 0 : return ret;
7824 : }
7825 :
7826 0 : static bool test_EnumPrinterKey(struct torture_context *tctx,
7827 : struct dcerpc_binding_handle *b,
7828 : struct policy_handle *handle,
7829 : const char *key_name,
7830 : const char ***array)
7831 : {
7832 : struct spoolss_EnumPrinterKey r;
7833 0 : uint32_t needed = 0;
7834 : union spoolss_KeyNames key_buffer;
7835 0 : int32_t offered[] = { 0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5, 256, 512, 1024, 2048 };
7836 : uint32_t _ndr_size;
7837 : int i;
7838 :
7839 0 : r.in.handle = handle;
7840 0 : r.in.key_name = key_name;
7841 0 : r.out.key_buffer = &key_buffer;
7842 0 : r.out.needed = &needed;
7843 0 : r.out._ndr_size = &_ndr_size;
7844 :
7845 0 : for (i=0; i < ARRAY_SIZE(offered); i++) {
7846 :
7847 0 : if (offered[i] < 0 && needed) {
7848 0 : if (needed <= 4) {
7849 0 : continue;
7850 : }
7851 0 : r.in.offered = needed + offered[i];
7852 : } else {
7853 0 : r.in.offered = offered[i];
7854 : }
7855 :
7856 0 : ZERO_STRUCT(key_buffer);
7857 :
7858 0 : torture_comment(tctx, "Testing EnumPrinterKey(%s) with %d offered\n", r.in.key_name, r.in.offered);
7859 :
7860 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &r),
7861 : "failed to call EnumPrinterKey");
7862 0 : if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
7863 :
7864 0 : torture_assert(tctx, (_ndr_size == r.in.offered/2),
7865 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7866 : _ndr_size, r.in.offered/2));
7867 :
7868 0 : r.in.offered = needed;
7869 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &r),
7870 : "failed to call EnumPrinterKey");
7871 : }
7872 :
7873 0 : if (offered[i] > 0) {
7874 0 : torture_assert_werr_ok(tctx, r.out.result,
7875 : "failed to call EnumPrinterKey");
7876 : }
7877 :
7878 0 : torture_assert(tctx, (_ndr_size == r.in.offered/2),
7879 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch, _ndr_size %d (expected %d)",
7880 : _ndr_size, r.in.offered/2));
7881 :
7882 0 : torture_assert(tctx, (*r.out.needed <= r.in.offered),
7883 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= offered %d", *r.out.needed, r.in.offered));
7884 :
7885 0 : torture_assert(tctx, (*r.out.needed <= _ndr_size * 2),
7886 : talloc_asprintf(tctx, "EnumPrinterKey size mismatch: needed %d is not <= _ndr_size %d * 2", *r.out.needed, _ndr_size));
7887 :
7888 0 : if (key_buffer.string_array) {
7889 0 : uint32_t calc_needed = 0;
7890 : int s;
7891 0 : for (s=0; key_buffer.string_array[s]; s++) {
7892 0 : calc_needed += strlen_m_term(key_buffer.string_array[s])*2;
7893 : }
7894 0 : if (!key_buffer.string_array[0]) {
7895 0 : calc_needed += 2;
7896 : }
7897 0 : calc_needed += 2;
7898 :
7899 0 : torture_assert_int_equal(tctx, *r.out.needed, calc_needed,
7900 : "EnumPrinterKey unexpected size");
7901 : }
7902 : }
7903 :
7904 0 : if (array) {
7905 0 : *array = key_buffer.string_array;
7906 : }
7907 :
7908 0 : return true;
7909 : }
7910 :
7911 0 : bool test_printer_all_keys(struct torture_context *tctx,
7912 : struct dcerpc_binding_handle *b,
7913 : struct policy_handle *handle)
7914 : {
7915 0 : const char **key_array = NULL;
7916 : int i;
7917 :
7918 0 : torture_comment(tctx, "Testing Printer Keys\n");
7919 :
7920 0 : torture_assert(tctx, test_EnumPrinterKey(tctx, b, handle, "", &key_array),
7921 : "failed to call test_EnumPrinterKey");
7922 :
7923 0 : for (i=0; key_array && key_array[i]; i++) {
7924 0 : torture_assert(tctx, test_EnumPrinterKey(tctx, b, handle, key_array[i], NULL),
7925 : "failed to call test_EnumPrinterKey");
7926 : }
7927 0 : for (i=0; key_array && key_array[i]; i++) {
7928 0 : torture_assert(tctx, test_EnumPrinterDataEx(tctx, b, handle, key_array[i], NULL, NULL),
7929 : "failed to call test_EnumPrinterDataEx");
7930 : }
7931 :
7932 0 : torture_comment(tctx, "Printer Keys test succeeded\n\n");
7933 :
7934 0 : return true;
7935 : }
7936 :
7937 0 : static bool test_openprinter_wrap(struct torture_context *tctx,
7938 : void *private_data)
7939 : {
7940 0 : struct torture_printer_context *t =
7941 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7942 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
7943 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7944 0 : const char *printername = t->info2.printername;
7945 :
7946 0 : return test_openprinter(tctx, b, printername);
7947 : }
7948 :
7949 0 : static bool test_csetprinter(struct torture_context *tctx,
7950 : void *private_data)
7951 : {
7952 0 : struct torture_printer_context *t =
7953 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
7954 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
7955 :
7956 0 : const char *printername = talloc_asprintf(tctx, "%s2", t->info2.printername);
7957 0 : const char *drivername = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
7958 0 : const char *portname = t->info2.portname;
7959 :
7960 : union spoolss_PrinterInfo info;
7961 : struct policy_handle new_handle, new_handle2;
7962 0 : struct dcerpc_binding_handle *b = p->binding_handle;
7963 :
7964 0 : torture_comment(tctx, "Testing c_setprinter\n");
7965 :
7966 0 : torture_assert(tctx,
7967 : test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
7968 : "failed to get level 0 printer info");
7969 0 : torture_comment(tctx, "csetprinter on initial printer handle: %d\n",
7970 : info.info0.c_setprinter);
7971 :
7972 : /* check if c_setprinter on 1st handle increases after a printer has
7973 : * been added */
7974 :
7975 0 : torture_assert(tctx,
7976 : test_AddPrinter_normal(tctx, p, &new_handle, printername, drivername, portname, NULL, false),
7977 : "failed to add new printer");
7978 0 : torture_assert(tctx,
7979 : test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
7980 : "failed to get level 0 printer info");
7981 0 : torture_comment(tctx, "csetprinter on initial printer handle (after add): %d\n",
7982 : info.info0.c_setprinter);
7983 :
7984 : /* check if c_setprinter on new handle increases after a printer has
7985 : * been added */
7986 :
7987 0 : torture_assert(tctx,
7988 : test_GetPrinter_level(tctx, b, &new_handle, 0, &info),
7989 : "failed to get level 0 printer info");
7990 0 : torture_comment(tctx, "csetprinter on created handle: %d\n",
7991 : info.info0.c_setprinter);
7992 :
7993 : /* open the new printer and check if c_setprinter increases */
7994 :
7995 0 : torture_assert(tctx,
7996 : call_OpenPrinterEx(tctx, p, printername, NULL, &new_handle2),
7997 : "failed to open created printer");
7998 0 : torture_assert(tctx,
7999 : test_GetPrinter_level(tctx, b, &new_handle2, 0, &info),
8000 : "failed to get level 0 printer info");
8001 0 : torture_comment(tctx, "csetprinter on new handle (after openprinter): %d\n",
8002 : info.info0.c_setprinter);
8003 :
8004 : /* cleanup */
8005 :
8006 0 : torture_assert(tctx,
8007 : test_ClosePrinter(tctx, b, &new_handle2),
8008 : "failed to close printer");
8009 0 : torture_assert(tctx,
8010 : test_DeletePrinter(tctx, b, &new_handle),
8011 : "failed to delete new printer");
8012 :
8013 0 : return true;
8014 : }
8015 :
8016 0 : static bool compose_local_driver_directory(struct torture_context *tctx,
8017 : const char *environment,
8018 : const char *local_dir,
8019 : const char **path)
8020 : {
8021 : char *p;
8022 :
8023 0 : p = strrchr(local_dir, '/');
8024 0 : if (!p) {
8025 0 : return NULL;
8026 : }
8027 0 : p++;
8028 :
8029 0 : if (strequal(environment, SPOOLSS_ARCHITECTURE_x64)) {
8030 0 : if (!strequal(p, "x64")) {
8031 0 : *path = talloc_asprintf(tctx, "%s/x64", local_dir);
8032 : }
8033 0 : } else if (strequal(environment, SPOOLSS_ARCHITECTURE_NT_X86)) {
8034 0 : if (!strequal(p, "i386")) {
8035 0 : *path = talloc_asprintf(tctx, "%s/i386", local_dir);
8036 : }
8037 : } else {
8038 : torture_assert(tctx, "unknown environment: '%s'\n", environment);
8039 : }
8040 :
8041 0 : return true;
8042 : }
8043 :
8044 : #if 0
8045 : static struct spoolss_DeviceMode *torture_devicemode(TALLOC_CTX *mem_ctx,
8046 : const char *devicename)
8047 : {
8048 : struct spoolss_DeviceMode *r;
8049 :
8050 : r = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
8051 : if (r == NULL) {
8052 : return NULL;
8053 : }
8054 :
8055 : r->devicename = talloc_strdup(r, devicename);
8056 : r->specversion = DMSPEC_NT4_AND_ABOVE;
8057 : r->driverversion = 0x0600;
8058 : r->size = 0x00dc;
8059 : r->__driverextra_length = 0;
8060 : r->fields = DEVMODE_FORMNAME |
8061 : DEVMODE_TTOPTION |
8062 : DEVMODE_PRINTQUALITY |
8063 : DEVMODE_DEFAULTSOURCE |
8064 : DEVMODE_COPIES |
8065 : DEVMODE_SCALE |
8066 : DEVMODE_PAPERSIZE |
8067 : DEVMODE_ORIENTATION;
8068 : r->orientation = DMORIENT_PORTRAIT;
8069 : r->papersize = DMPAPER_LETTER;
8070 : r->paperlength = 0;
8071 : r->paperwidth = 0;
8072 : r->scale = 100;
8073 : r->copies = 55;
8074 : r->defaultsource = DMBIN_FORMSOURCE;
8075 : r->printquality = DMRES_HIGH;
8076 : r->color = DMRES_MONOCHROME;
8077 : r->duplex = DMDUP_SIMPLEX;
8078 : r->yresolution = 0;
8079 : r->ttoption = DMTT_SUBDEV;
8080 : r->collate = DMCOLLATE_FALSE;
8081 : r->formname = talloc_strdup(r, "Letter");
8082 :
8083 : return r;
8084 : }
8085 : #endif
8086 :
8087 0 : static bool test_architecture_buffer(struct torture_context *tctx,
8088 : void *private_data)
8089 : {
8090 0 : struct test_spoolss_context *ctx =
8091 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8092 :
8093 : struct spoolss_OpenPrinterEx r;
8094 : struct spoolss_UserLevel1 u1;
8095 : struct policy_handle handle;
8096 0 : uint32_t architectures[] = {
8097 : PROCESSOR_ARCHITECTURE_INTEL,
8098 : PROCESSOR_ARCHITECTURE_IA64,
8099 : PROCESSOR_ARCHITECTURE_AMD64
8100 : };
8101 : uint32_t needed[3];
8102 : int i;
8103 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8104 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8105 :
8106 0 : for (i=0; i < ARRAY_SIZE(architectures); i++) {
8107 :
8108 0 : torture_comment(tctx, "Testing OpenPrinterEx with architecture %d\n", architectures[i]);
8109 :
8110 0 : u1.size = 0;
8111 0 : u1.client = NULL;
8112 0 : u1.user = NULL;
8113 0 : u1.build = 0;
8114 0 : u1.major = 3;
8115 0 : u1.minor = 0;
8116 0 : u1.processor = architectures[i];
8117 :
8118 0 : r.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8119 0 : r.in.datatype = NULL;
8120 0 : r.in.devmode_ctr.devmode= NULL;
8121 0 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
8122 0 : r.in.userlevel_ctr.level = 1;
8123 0 : r.in.userlevel_ctr.user_info.level1 = &u1;
8124 0 : r.out.handle = &handle;
8125 :
8126 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r), "");
8127 0 : torture_assert_werr_ok(tctx, r.out.result, "");
8128 :
8129 : {
8130 : struct spoolss_EnumPrinters e;
8131 : uint32_t count;
8132 : union spoolss_PrinterInfo *info;
8133 :
8134 0 : e.in.flags = PRINTER_ENUM_LOCAL;
8135 0 : e.in.server = NULL;
8136 0 : e.in.level = 2;
8137 0 : e.in.buffer = NULL;
8138 0 : e.in.offered = 0;
8139 0 : e.out.count = &count;
8140 0 : e.out.info = &info;
8141 0 : e.out.needed = &needed[i];
8142 :
8143 0 : torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e), "");
8144 : #if 0
8145 : torture_comment(tctx, "needed was %d\n", needed[i]);
8146 : #endif
8147 : }
8148 :
8149 0 : torture_assert(tctx, test_ClosePrinter(tctx, b, &handle), "");
8150 : }
8151 :
8152 0 : for (i=1; i < ARRAY_SIZE(architectures); i++) {
8153 0 : if (needed[i-1] != needed[i]) {
8154 0 : torture_fail(tctx,
8155 : talloc_asprintf(tctx, "needed size %d for architecture %d != needed size %d for architecture %d\n",
8156 : needed[i-1], architectures[i-1], needed[i], architectures[i]));
8157 : }
8158 : }
8159 :
8160 0 : return true;
8161 : }
8162 :
8163 0 : static bool test_get_core_printer_drivers_arch_guid(struct torture_context *tctx,
8164 : struct dcerpc_pipe *p,
8165 : const char *architecture,
8166 : const char *guid_str,
8167 : const char **package_id)
8168 : {
8169 : struct spoolss_GetCorePrinterDrivers r;
8170 : struct spoolss_CorePrinterDriver core_printer_drivers;
8171 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 2);
8172 : const char **s;
8173 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8174 : struct GUID guid;
8175 :
8176 0 : s = talloc_zero_array(tctx, const char *, 2);
8177 :
8178 0 : r.in.servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8179 0 : r.in.architecture = "foobar";
8180 0 : r.in.core_driver_size = 0;
8181 0 : r.in.core_driver_dependencies = (uint16_t *)blob.data;
8182 0 : r.in.core_printer_driver_count = 0;
8183 0 : r.out.core_printer_drivers = &core_printer_drivers;
8184 :
8185 0 : torture_assert_ntstatus_ok(tctx,
8186 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8187 : "spoolss_GetCorePrinterDrivers failed");
8188 0 : torture_assert_hresult_equal(tctx, r.out.result, HRES_E_INVALIDARG,
8189 : "spoolss_GetCorePrinterDrivers failed");
8190 :
8191 0 : guid = GUID_random();
8192 0 : s[0] = GUID_string2(tctx, &guid);
8193 :
8194 0 : torture_assert(tctx,
8195 : push_reg_multi_sz(tctx, &blob, s),
8196 : "push_reg_multi_sz failed");
8197 :
8198 0 : r.in.core_driver_size = blob.length/2;
8199 0 : r.in.core_driver_dependencies = (uint16_t *)blob.data;
8200 0 : r.in.core_printer_driver_count = 1;
8201 0 : r.out.core_printer_drivers = talloc_zero_array(tctx, struct spoolss_CorePrinterDriver, r.in.core_printer_driver_count);
8202 :
8203 0 : torture_assert_ntstatus_ok(tctx,
8204 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8205 : "spoolss_GetCorePrinterDrivers failed");
8206 0 : torture_assert_werr_equal(tctx,
8207 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
8208 : "spoolss_GetCorePrinterDrivers failed");
8209 :
8210 0 : r.in.architecture = architecture;
8211 :
8212 0 : torture_assert_ntstatus_ok(tctx,
8213 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8214 : "spoolss_GetCorePrinterDrivers failed");
8215 0 : torture_assert_werr_equal(tctx,
8216 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_NOT_FOUND,
8217 : "spoolss_GetCorePrinterDrivers failed");
8218 :
8219 0 : s[0] = talloc_strdup(s, guid_str);
8220 :
8221 0 : torture_assert(tctx,
8222 : push_reg_multi_sz(tctx, &blob, s),
8223 : "push_reg_multi_sz failed");
8224 :
8225 0 : r.in.core_driver_size = blob.length/2;
8226 0 : r.in.core_driver_dependencies = (uint16_t *)blob.data;
8227 0 : r.in.core_printer_driver_count = 1;
8228 0 : r.out.core_printer_drivers = talloc_zero_array(tctx, struct spoolss_CorePrinterDriver, r.in.core_printer_driver_count);
8229 :
8230 0 : torture_assert_ntstatus_ok(tctx,
8231 : dcerpc_spoolss_GetCorePrinterDrivers_r(b, tctx, &r),
8232 : "spoolss_GetCorePrinterDrivers failed");
8233 0 : torture_assert_hresult_ok(tctx, r.out.result,
8234 : "spoolss_GetCorePrinterDrivers failed");
8235 :
8236 0 : if (package_id) {
8237 0 : *package_id = r.out.core_printer_drivers[0].szPackageID;
8238 : }
8239 :
8240 0 : return true;
8241 : }
8242 :
8243 0 : static bool test_get_core_printer_drivers(struct torture_context *tctx,
8244 : void *private_data)
8245 : {
8246 0 : struct test_spoolss_context *ctx =
8247 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8248 :
8249 0 : const char *architectures[] = {
8250 : SPOOLSS_ARCHITECTURE_NT_X86,
8251 : SPOOLSS_ARCHITECTURE_x64
8252 : };
8253 : int i;
8254 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8255 :
8256 0 : for (i=0; i < ARRAY_SIZE(architectures); i++) {
8257 :
8258 0 : torture_comment(tctx, "Testing GetCorePrinterDrivers(\"%s\",\"%s\")\n",
8259 : architectures[i],
8260 : SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV);
8261 :
8262 0 : torture_assert(tctx,
8263 : test_get_core_printer_drivers_arch_guid(tctx, p,
8264 : architectures[i],
8265 : SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV,
8266 : NULL),
8267 : "");
8268 : }
8269 :
8270 0 : return true;
8271 : }
8272 :
8273 0 : static bool test_get_printer_driver_package_path(struct torture_context *tctx,
8274 : void *private_data)
8275 : {
8276 0 : struct test_spoolss_context *ctx =
8277 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8278 :
8279 0 : const char *architectures[] = {
8280 : SPOOLSS_ARCHITECTURE_NT_X86,
8281 : SPOOLSS_ARCHITECTURE_x64
8282 : };
8283 : int i;
8284 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8285 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8286 :
8287 0 : for (i=0; i < ARRAY_SIZE(architectures); i++) {
8288 : struct spoolss_GetPrinterDriverPackagePath r;
8289 0 : uint32_t required = 0;
8290 0 : const char *package_id = NULL;
8291 :
8292 0 : test_get_core_printer_drivers_arch_guid(tctx, p,
8293 : architectures[i],
8294 : SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV,
8295 : &package_id),
8296 :
8297 0 : torture_comment(tctx, "Testing GetPrinterDriverPackagePath(\"%s\",\"%s\")\n",
8298 : architectures[i], package_id);
8299 :
8300 0 : r.in.servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8301 0 : r.in.architecture = "foobar";
8302 0 : r.in.language = NULL;
8303 0 : r.in.package_id = "";
8304 0 : r.in.driver_package_cab_size = 0;
8305 0 : r.in.driver_package_cab = NULL;
8306 :
8307 0 : r.out.required = &required;
8308 0 : r.out.driver_package_cab = NULL;
8309 :
8310 0 : torture_assert_ntstatus_ok(tctx,
8311 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8312 : "spoolss_GetPrinterDriverPackagePath failed");
8313 0 : torture_assert_werr_equal(tctx,
8314 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INVALID_ENVIRONMENT,
8315 : "spoolss_GetPrinterDriverPackagePath failed");
8316 :
8317 0 : r.in.architecture = architectures[i];
8318 :
8319 0 : torture_assert_ntstatus_ok(tctx,
8320 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8321 : "spoolss_GetPrinterDriverPackagePath failed");
8322 0 : torture_assert_werr_equal(tctx,
8323 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_FILE_NOT_FOUND,
8324 : "spoolss_GetPrinterDriverPackagePath failed");
8325 :
8326 0 : r.in.package_id = package_id;
8327 :
8328 0 : torture_assert_ntstatus_ok(tctx,
8329 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8330 : "spoolss_GetPrinterDriverPackagePath failed");
8331 0 : torture_assert_hresult_ok(tctx, r.out.result,
8332 : "spoolss_GetPrinterDriverPackagePath failed");
8333 :
8334 0 : r.in.driver_package_cab_size = required;
8335 0 : r.in.driver_package_cab = talloc_zero_array(tctx, char, required);
8336 0 : r.out.driver_package_cab = talloc_zero_array(tctx, char, required);
8337 :
8338 0 : torture_assert_ntstatus_ok(tctx,
8339 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8340 : "spoolss_GetPrinterDriverPackagePath failed");
8341 0 : torture_assert_hresult_ok(tctx, r.out.result,
8342 : "spoolss_GetPrinterDriverPackagePath failed");
8343 :
8344 0 : r.in.servername = NULL;
8345 :
8346 0 : torture_assert_ntstatus_ok(tctx,
8347 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8348 : "spoolss_GetPrinterDriverPackagePath failed");
8349 0 : torture_assert_werr_equal(tctx,
8350 : W_ERROR(WIN32_FROM_HRESULT(r.out.result)), WERR_INSUFFICIENT_BUFFER,
8351 : "spoolss_GetPrinterDriverPackagePath failed");
8352 :
8353 0 : r.in.driver_package_cab_size = required;
8354 0 : r.in.driver_package_cab = talloc_zero_array(tctx, char, required);
8355 0 : r.out.driver_package_cab = talloc_zero_array(tctx, char, required);
8356 :
8357 0 : torture_assert_ntstatus_ok(tctx,
8358 : dcerpc_spoolss_GetPrinterDriverPackagePath_r(b, tctx, &r),
8359 : "spoolss_GetPrinterDriverPackagePath failed");
8360 0 : torture_assert_hresult_ok(tctx, r.out.result,
8361 : "spoolss_GetPrinterDriverPackagePath failed");
8362 :
8363 : }
8364 :
8365 0 : return true;
8366 : }
8367 :
8368 0 : static bool test_get_printer_printserverhandle(struct torture_context *tctx,
8369 : void *private_data)
8370 : {
8371 0 : struct test_spoolss_context *ctx =
8372 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8373 :
8374 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8375 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8376 0 : uint32_t levels[] = {0, 1, 2, /* 3,*/ 4, 5, 6, 7, 8};
8377 : int i;
8378 :
8379 0 : for (i=0;i<ARRAY_SIZE(levels);i++) {
8380 :
8381 0 : torture_assert(tctx,
8382 : test_GetPrinter_level_exp(tctx, b, &ctx->server_handle,
8383 : levels[i], WERR_INVALID_LEVEL,
8384 : NULL),
8385 : "failed to call GetPrinter");
8386 : }
8387 :
8388 0 : torture_assert(tctx,
8389 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, NULL),
8390 : "failed to call GetPrinter");
8391 :
8392 0 : return true;
8393 : }
8394 :
8395 : #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
8396 :
8397 0 : static bool test_set_printer_printserverhandle(struct torture_context *tctx,
8398 : void *private_data)
8399 : {
8400 0 : struct test_spoolss_context *ctx =
8401 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8402 :
8403 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8404 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8405 : union spoolss_PrinterInfo info;
8406 : struct spoolss_SetPrinterInfoCtr info_ctr;
8407 : struct spoolss_SetPrinterInfo3 info3;
8408 : struct spoolss_DevmodeContainer devmode_ctr;
8409 : struct sec_desc_buf secdesc_ctr;
8410 : struct security_descriptor *sd;
8411 : struct security_ace *ace;
8412 : struct dom_sid sid;
8413 : int i;
8414 :
8415 0 : torture_assert(tctx,
8416 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, &info),
8417 : "failed to call GetPrinter");
8418 :
8419 0 : secdesc_ctr.sd = info.info3.secdesc;
8420 0 : secdesc_ctr.sd->owner_sid = NULL;
8421 0 : secdesc_ctr.sd->group_sid = NULL;
8422 :
8423 0 : sd = security_descriptor_copy(tctx, secdesc_ctr.sd);
8424 0 : if (sd == NULL) {
8425 0 : return false;
8426 : }
8427 :
8428 0 : ace = security_ace_create(tctx,
8429 : TEST_SID,
8430 : SEC_ACE_TYPE_ACCESS_ALLOWED,
8431 : SEC_STD_REQUIRED,
8432 : SEC_ACE_FLAG_CONTAINER_INHERIT);
8433 0 : torture_assert(tctx, ace, "failed to create ace");
8434 :
8435 0 : torture_assert_ntstatus_ok(tctx,
8436 : security_descriptor_dacl_add(sd, ace),
8437 : "failed to add ace");
8438 :
8439 0 : secdesc_ctr.sd = sd;
8440 :
8441 0 : info3.sec_desc_ptr = 0;
8442 :
8443 0 : info_ctr.level = 3;
8444 0 : info_ctr.info.info3 = &info3;
8445 :
8446 0 : ZERO_STRUCT(devmode_ctr);
8447 :
8448 0 : torture_assert(tctx,
8449 : test_SetPrinter(tctx, b, &ctx->server_handle, &info_ctr,
8450 : &devmode_ctr, &secdesc_ctr, 0),
8451 : "failed to call SetPrinter");
8452 :
8453 0 : torture_assert(tctx,
8454 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, &info),
8455 : "failed to call GetPrinter");
8456 :
8457 0 : for (i = 0; i < info.info3.secdesc->dacl->num_aces; i++) {
8458 0 : if (security_ace_equal(&info.info3.secdesc->dacl->aces[i], ace)) {
8459 0 : break;
8460 : }
8461 : }
8462 :
8463 0 : if (i == info.info3.secdesc->dacl->num_aces) {
8464 0 : torture_fail(tctx, "ace not present");
8465 : }
8466 :
8467 0 : torture_assert(tctx,
8468 : dom_sid_parse(TEST_SID, &sid),
8469 : "failed to parse sid");
8470 :
8471 0 : torture_assert_ntstatus_ok(tctx,
8472 : security_descriptor_dacl_del(info.info3.secdesc, &sid),
8473 : "failed to remove ace from sd");
8474 :
8475 0 : secdesc_ctr.sd = info.info3.secdesc;
8476 :
8477 0 : torture_assert(tctx,
8478 : test_SetPrinter(tctx, b, &ctx->server_handle, &info_ctr,
8479 : &devmode_ctr, &secdesc_ctr, 0),
8480 : "failed to call SetPrinter");
8481 :
8482 0 : torture_assert(tctx,
8483 : test_GetPrinter_level(tctx, b, &ctx->server_handle, 3, &info),
8484 : "failed to call GetPrinter");
8485 :
8486 0 : for (i = 0; i < info.info3.secdesc->dacl->num_aces; i++) {
8487 0 : if (security_ace_equal(&info.info3.secdesc->dacl->aces[i], ace)) {
8488 0 : torture_fail(tctx, "ace still present");
8489 : }
8490 : }
8491 :
8492 0 : return true;
8493 : }
8494 :
8495 :
8496 0 : static bool test_PrintServer_Forms_Winreg(struct torture_context *tctx,
8497 : void *private_data)
8498 : {
8499 0 : struct test_spoolss_context *ctx =
8500 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8501 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8502 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8503 :
8504 0 : return test_Forms_winreg(tctx, b, &ctx->server_handle, true, NULL);
8505 : }
8506 :
8507 0 : static bool test_PrintServer_Forms(struct torture_context *tctx,
8508 : void *private_data)
8509 : {
8510 0 : struct test_spoolss_context *ctx =
8511 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8512 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8513 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8514 :
8515 0 : return test_Forms(tctx, b, &ctx->server_handle, true, NULL, NULL, NULL);
8516 : }
8517 :
8518 0 : static bool test_PrintServer_EnumForms(struct torture_context *tctx,
8519 : void *private_data)
8520 : {
8521 0 : struct test_spoolss_context *ctx =
8522 0 : talloc_get_type_abort(private_data, struct test_spoolss_context);
8523 0 : struct dcerpc_pipe *p = ctx->spoolss_pipe;
8524 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8525 :
8526 0 : return test_EnumForms_all(tctx, b, &ctx->server_handle, true);
8527 : }
8528 :
8529 0 : static bool torture_rpc_spoolss_setup_common(struct torture_context *tctx, struct test_spoolss_context *t)
8530 : {
8531 : NTSTATUS status;
8532 :
8533 0 : status = torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss);
8534 :
8535 0 : torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
8536 :
8537 0 : torture_assert(tctx,
8538 : test_OpenPrinter_server(tctx, t->spoolss_pipe, &t->server_handle),
8539 : "failed to open printserver");
8540 0 : torture_assert(tctx,
8541 : test_get_environment(tctx, t->spoolss_pipe->binding_handle, &t->server_handle, &t->environment),
8542 : "failed to get environment");
8543 :
8544 0 : return true;
8545 : }
8546 :
8547 0 : static bool torture_rpc_spoolss_setup(struct torture_context *tctx, void **data)
8548 : {
8549 : struct test_spoolss_context *t;
8550 :
8551 0 : *data = t = talloc_zero(tctx, struct test_spoolss_context);
8552 :
8553 0 : return torture_rpc_spoolss_setup_common(tctx, t);
8554 : }
8555 :
8556 0 : static bool torture_rpc_spoolss_teardown_common(struct torture_context *tctx, struct test_spoolss_context *t)
8557 : {
8558 0 : test_ClosePrinter(tctx, t->spoolss_pipe->binding_handle, &t->server_handle);
8559 :
8560 0 : return true;
8561 : }
8562 :
8563 0 : static bool torture_rpc_spoolss_teardown(struct torture_context *tctx, void *data)
8564 : {
8565 0 : struct test_spoolss_context *t = talloc_get_type(data, struct test_spoolss_context);
8566 : bool ret;
8567 :
8568 0 : ret = torture_rpc_spoolss_teardown_common(tctx, t);
8569 0 : talloc_free(t);
8570 :
8571 0 : return ret;
8572 : }
8573 :
8574 0 : static bool torture_rpc_spoolss_printer_setup_common(struct torture_context *tctx, struct torture_printer_context *t)
8575 : {
8576 : struct dcerpc_pipe *p;
8577 : struct dcerpc_binding_handle *b;
8578 : const char *server_name_slash;
8579 : const char *driver_name;
8580 : const char *printer_name;
8581 : const char *port_name;
8582 :
8583 0 : torture_assert_ntstatus_ok(tctx,
8584 : torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss),
8585 : "Error connecting to server");
8586 :
8587 0 : p = t->spoolss_pipe;
8588 0 : b = p->binding_handle;
8589 0 : server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8590 :
8591 0 : t->driver.info8.version = SPOOLSS_DRIVER_VERSION_200X;
8592 0 : t->driver.info8.driver_name = TORTURE_DRIVER;
8593 0 : t->driver.info8.driver_path = "pscript5.dll";
8594 0 : t->driver.info8.data_file = "cups6.ppd";
8595 0 : t->driver.info8.config_file = "ps5ui.dll";
8596 0 : t->driver.info8.help_file = "pscript.hlp";
8597 0 : t->driver.info8.default_datatype = "RAW";
8598 0 : t->driver.info8.dependent_files = talloc_zero(t, struct spoolss_StringArray);
8599 0 : t->driver.info8.dependent_files->string = talloc_zero_array(t, const char *, 8 + 1);
8600 0 : t->driver.info8.dependent_files->string[0] = "pscript5.dll";
8601 0 : t->driver.info8.dependent_files->string[1] = "cups6.ppd";
8602 0 : t->driver.info8.dependent_files->string[2] = "ps5ui.dll";
8603 0 : t->driver.info8.dependent_files->string[3] = "pscript.hlp";
8604 0 : t->driver.info8.dependent_files->string[4] = "pscript.ntf";
8605 0 : t->driver.info8.dependent_files->string[5] = "cups6.ini";
8606 0 : t->driver.info8.dependent_files->string[6] = "cupsps6.dll";
8607 0 : t->driver.info8.dependent_files->string[7] = "cupsui6.dll";
8608 :
8609 0 : t->driver.local.driver_directory= "/usr/share/cups/drivers";
8610 :
8611 0 : t->info2.portname = "LPT1:";
8612 :
8613 0 : printer_name = t->info2.printername;
8614 0 : port_name = t->info2.portname;
8615 :
8616 0 : torture_assert(tctx,
8617 : fillup_printserver_info(tctx, p, &t->driver),
8618 : "failed to fillup printserver info");
8619 :
8620 0 : t->driver.info8.architecture = talloc_strdup(t, t->driver.remote.environment);
8621 :
8622 0 : torture_assert(tctx,
8623 : compose_local_driver_directory(tctx, t->driver.remote.environment,
8624 : t->driver.local.driver_directory,
8625 : &t->driver.local.driver_directory),
8626 : "failed to compose local driver directory");
8627 :
8628 0 : t->info2.drivername = "Microsoft XPS Document Writer";
8629 :
8630 0 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, t->driver.remote.environment, 3, t->info2.drivername, NULL)) {
8631 0 : torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) is present on server\n",
8632 : t->info2.drivername, t->driver.remote.environment);
8633 0 : t->have_driver = true;
8634 0 : goto try_add;
8635 : }
8636 :
8637 0 : torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) does not exist on the server\n",
8638 : t->info2.drivername, t->driver.remote.environment);
8639 :
8640 0 : t->info2.drivername = "Microsoft XPS Document Writer v4";
8641 :
8642 0 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, t->driver.remote.environment, 3, t->info2.drivername, NULL)) {
8643 0 : torture_comment(tctx, "driver '%s' (architecture: %s, version: 4) is present on server\n",
8644 : t->info2.drivername, t->driver.remote.environment);
8645 0 : t->have_driver = true;
8646 0 : goto try_add;
8647 : }
8648 :
8649 0 : torture_comment(tctx, "trying to upload own driver\n");
8650 :
8651 0 : if (!directory_exist(t->driver.local.driver_directory)) {
8652 0 : torture_warning(tctx, "no local driver is available!");
8653 0 : t->have_driver = false;
8654 0 : goto try_add;
8655 : }
8656 :
8657 0 : torture_assert(tctx,
8658 : upload_printer_driver(tctx, dcerpc_server_name(p), &t->driver),
8659 : "failed to upload printer driver");
8660 :
8661 0 : torture_assert(tctx,
8662 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &t->driver.info8, 0, false, NULL),
8663 : "failed to add driver");
8664 :
8665 0 : t->added_driver = true;
8666 0 : t->have_driver = true;
8667 :
8668 0 : try_add:
8669 0 : driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
8670 :
8671 0 : if (t->wellknown) {
8672 0 : torture_assert(tctx,
8673 : test_AddPrinter_wellknown(tctx, p, printer_name, t->ex),
8674 : "failed to add wellknown printer");
8675 : } else {
8676 0 : torture_assert(tctx,
8677 : test_AddPrinter_normal(tctx, p, &t->handle, printer_name, driver_name, port_name, t->devmode, t->ex),
8678 : "failed to add printer");
8679 : }
8680 :
8681 0 : return true;
8682 : }
8683 :
8684 0 : static bool torture_rpc_spoolss_printer_setup(struct torture_context *tctx, void **data)
8685 : {
8686 : struct torture_printer_context *t;
8687 :
8688 0 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8689 :
8690 0 : t->ex = false;
8691 0 : t->wellknown = false;
8692 0 : t->info2.printername = TORTURE_PRINTER;
8693 0 : t->devmode = NULL;
8694 :
8695 0 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8696 : }
8697 :
8698 0 : static bool torture_rpc_spoolss_printerex_setup(struct torture_context *tctx, void **data)
8699 : {
8700 : struct torture_printer_context *t;
8701 :
8702 0 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8703 :
8704 0 : t->ex = true;
8705 0 : t->wellknown = false;
8706 0 : t->info2.printername = TORTURE_PRINTER_EX;
8707 0 : t->devmode = NULL;
8708 :
8709 0 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8710 : }
8711 :
8712 0 : static bool torture_rpc_spoolss_printerwkn_setup(struct torture_context *tctx, void **data)
8713 : {
8714 : struct torture_printer_context *t;
8715 :
8716 0 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8717 :
8718 0 : t->ex = false;
8719 0 : t->wellknown = true;
8720 0 : t->info2.printername = TORTURE_WELLKNOWN_PRINTER;
8721 0 : t->devmode = NULL;
8722 :
8723 : /* FIXME */
8724 0 : if (t->wellknown) {
8725 0 : torture_skip(tctx, "skipping AddPrinter level 1");
8726 : }
8727 :
8728 0 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8729 : }
8730 :
8731 0 : static bool torture_rpc_spoolss_printerexwkn_setup(struct torture_context *tctx, void **data)
8732 : {
8733 : struct torture_printer_context *t;
8734 :
8735 0 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8736 :
8737 0 : t->ex = true;
8738 0 : t->wellknown = true;
8739 0 : t->info2.printername = TORTURE_WELLKNOWN_PRINTER_EX;
8740 0 : t->devmode = NULL;
8741 :
8742 : /* FIXME */
8743 0 : if (t->wellknown) {
8744 0 : torture_skip(tctx, "skipping AddPrinterEx level 1");
8745 : }
8746 :
8747 0 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8748 : }
8749 :
8750 : #if 0
8751 : static bool torture_rpc_spoolss_printerdm_setup(struct torture_context *tctx, void **data)
8752 : {
8753 : struct torture_printer_context *t;
8754 :
8755 : *data = t = talloc_zero(tctx, struct torture_printer_context);
8756 :
8757 : t->ex = true;
8758 : t->wellknown = false;
8759 : t->info2.printername = TORTURE_PRINTER_EX;
8760 : t->devmode = torture_devicemode(t, TORTURE_PRINTER_EX);
8761 :
8762 : return torture_rpc_spoolss_printer_setup_common(tctx, t);
8763 : }
8764 : #endif
8765 :
8766 : static bool test_DeletePrinterDriverEx_exp(struct torture_context *tctx,
8767 : struct dcerpc_binding_handle *b,
8768 : const char *server,
8769 : const char *driver,
8770 : const char *environment,
8771 : uint32_t delete_flags,
8772 : uint32_t version,
8773 : WERROR expected_result);
8774 :
8775 0 : static bool torture_rpc_spoolss_printer_teardown_common(struct torture_context *tctx, struct torture_printer_context *t)
8776 : {
8777 0 : bool found = false;
8778 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
8779 0 : struct dcerpc_binding_handle *b = NULL;
8780 : const char *server_name_slash;
8781 0 : bool ok = true;
8782 :
8783 0 : if (p == NULL) {
8784 0 : return true;
8785 : }
8786 0 : b = p->binding_handle;
8787 :
8788 0 : server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
8789 :
8790 0 : if (!t->wellknown) {
8791 0 : const char *printer_name = t->info2.printername;
8792 :
8793 0 : torture_assert_goto(tctx,
8794 : test_DeletePrinter(tctx, b, &t->handle),
8795 : ok,
8796 : remove_driver,
8797 : "failed to delete printer");
8798 :
8799 0 : torture_assert_goto(tctx,
8800 : test_EnumPrinters_findname(tctx, b, PRINTER_ENUM_LOCAL, 1,
8801 : printer_name, &found),
8802 : ok,
8803 : remove_driver,
8804 : "failed to enumerate printers");
8805 :
8806 0 : torture_assert_goto(tctx,
8807 : !found,
8808 : ok,
8809 : remove_driver,
8810 : "deleted printer still there");
8811 : }
8812 :
8813 :
8814 0 : remove_driver:
8815 0 : if (t->added_driver) {
8816 0 : ok = remove_printer_driver(tctx,
8817 : dcerpc_server_name(p),
8818 : &t->driver);
8819 0 : if (!ok) {
8820 0 : torture_warning(tctx,
8821 : "failed to remove printer driver\n");
8822 : }
8823 :
8824 0 : ok = test_DeletePrinterDriverEx_exp(tctx, b,
8825 : server_name_slash,
8826 : t->driver.info8.driver_name,
8827 : t->driver.info8.architecture,
8828 : DPD_DELETE_ALL_FILES,
8829 0 : t->driver.info8.version,
8830 0 : WERR_OK);
8831 0 : if (!ok) {
8832 0 : torture_warning(tctx,
8833 : "failed to delete printer driver via "
8834 : "spoolss\n");
8835 : }
8836 : }
8837 :
8838 0 : return ok;
8839 : }
8840 :
8841 0 : static bool torture_rpc_spoolss_printer_teardown(struct torture_context *tctx, void *data)
8842 : {
8843 0 : struct torture_printer_context *t = talloc_get_type(data, struct torture_printer_context);
8844 : bool ret;
8845 :
8846 0 : ret = torture_rpc_spoolss_printer_teardown_common(tctx, t);
8847 0 : talloc_free(t);
8848 :
8849 0 : return ret;
8850 : }
8851 :
8852 0 : static bool test_print_test(struct torture_context *tctx,
8853 : void *private_data)
8854 : {
8855 0 : struct torture_printer_context *t =
8856 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8857 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
8858 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8859 :
8860 0 : torture_assert(tctx,
8861 : test_PausePrinter(tctx, b, &t->handle),
8862 : "failed to pause printer");
8863 :
8864 0 : torture_assert(tctx,
8865 : test_DoPrintTest(tctx, b, &t->handle),
8866 : "failed to do print test");
8867 :
8868 0 : torture_assert(tctx,
8869 : test_ResumePrinter(tctx, b, &t->handle),
8870 : "failed to resume printer");
8871 :
8872 0 : return true;
8873 : }
8874 :
8875 0 : static bool test_print_test_extended(struct torture_context *tctx,
8876 : void *private_data)
8877 : {
8878 0 : struct torture_printer_context *t =
8879 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8880 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
8881 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8882 0 : bool ret = true;
8883 :
8884 0 : torture_assert(tctx,
8885 : test_PausePrinter(tctx, b, &t->handle),
8886 : "failed to pause printer");
8887 :
8888 0 : ret = test_DoPrintTest_extended(tctx, b, &t->handle);
8889 0 : if (ret == false) {
8890 0 : torture_comment(tctx, "WARNING! failed to do extended print test\n");
8891 0 : if (torture_setting_bool(tctx, "samba3", false)) {
8892 0 : torture_comment(tctx, "non-critical for samba3\n");
8893 0 : ret = true;
8894 0 : tctx->last_result = TORTURE_SKIP;
8895 : }
8896 : }
8897 :
8898 0 : torture_assert(tctx,
8899 : test_ResumePrinter(tctx, b, &t->handle),
8900 : "failed to resume printer");
8901 :
8902 0 : return ret;
8903 : }
8904 :
8905 0 : static bool test_print_test_properties(struct torture_context *tctx,
8906 : void *private_data)
8907 : {
8908 0 : struct torture_printer_context *t =
8909 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8910 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
8911 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8912 :
8913 0 : if (torture_setting_bool(tctx, "samba3", false)) {
8914 0 : torture_skip(tctx, "skip printer job property tests against samba");
8915 : }
8916 :
8917 0 : torture_assert(tctx,
8918 : test_PausePrinter(tctx, b, &t->handle),
8919 : "failed to pause printer");
8920 :
8921 0 : torture_assert(tctx,
8922 : test_DoPrintTest_properties(tctx, b, &t->handle),
8923 : "failed to test print job properties");
8924 :
8925 0 : torture_assert(tctx,
8926 : test_ResumePrinter(tctx, b, &t->handle),
8927 : "failed to resume printer");
8928 :
8929 0 : return true;
8930 : }
8931 :
8932 : /* use smbd file IO to spool a print job */
8933 0 : static bool test_print_test_smbd(struct torture_context *tctx,
8934 : void *private_data)
8935 : {
8936 0 : struct torture_printer_context *t =
8937 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
8938 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
8939 0 : struct dcerpc_binding_handle *b = p->binding_handle;
8940 : NTSTATUS status;
8941 : uint32_t count;
8942 0 : union spoolss_JobInfo *info = NULL;
8943 : int i;
8944 :
8945 : struct smb2_tree *tree;
8946 : struct smb2_handle job_h;
8947 : struct smbcli_options options;
8948 0 : TALLOC_CTX *mem_ctx = talloc_new(tctx);
8949 : /*
8950 : * Do not test against the dynamically added printers, printing via
8951 : * smbd means that a different spoolss process may handle the
8952 : * OpenPrinter request to the one that handled the AddPrinter request.
8953 : * This currently leads to an ugly race condition where one process
8954 : * sees the new printer and one doesn't.
8955 : */
8956 0 : const char *share = TORTURE_PRINTER_STATIC1;
8957 :
8958 0 : torture_comment(tctx, "Testing smbd job spooling\n");
8959 0 : lpcfg_smbcli_options(tctx->lp_ctx, &options);
8960 :
8961 0 : status = smb2_connect(mem_ctx,
8962 : torture_setting_string(tctx, "host", NULL),
8963 : lpcfg_smb_ports(tctx->lp_ctx),
8964 : share,
8965 : lpcfg_resolve_context(tctx->lp_ctx),
8966 : samba_cmdline_get_creds(),
8967 : &tree,
8968 : tctx->ev,
8969 : &options,
8970 : lpcfg_socket_options(tctx->lp_ctx),
8971 : lpcfg_gensec_settings(tctx, tctx->lp_ctx));
8972 0 : if (!NT_STATUS_IS_OK(status)) {
8973 0 : printf("Failed to connect to SMB2 printer %s - %s\n",
8974 : share, nt_errstr(status));
8975 0 : return false;
8976 : }
8977 :
8978 0 : status = torture_smb2_testfile(tree, "smbd_spooler_job", &job_h);
8979 0 : torture_assert_ntstatus_ok(tctx, status, "smbd spool job create");
8980 :
8981 0 : status = smb2_util_write(tree, job_h, "exciting print job data", 0,
8982 : sizeof("exciting print job data"));
8983 0 : torture_assert_ntstatus_ok(tctx, status, "smbd spool job write");
8984 :
8985 : /* check back end spoolss job was created */
8986 0 : torture_assert(tctx,
8987 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
8988 : &count, &info),
8989 : "EnumJobs level 1 failed");
8990 :
8991 0 : for (i = 0; i < count; i++) {
8992 0 : if (!strcmp(info[i].info1.document_name, "smbd_spooler_job")) {
8993 0 : break;
8994 : }
8995 : }
8996 0 : torture_assert(tctx, (i != count), "smbd_spooler_job not found");
8997 :
8998 0 : status = smb2_util_close(tree, job_h);
8999 0 : torture_assert_ntstatus_ok(tctx, status, "smbd spool job close");
9000 :
9001 : /* disconnect from printer share */
9002 0 : talloc_free(mem_ctx);
9003 :
9004 0 : return true;
9005 : }
9006 :
9007 0 : static bool test_print_test_purge(struct torture_context *tctx,
9008 : void *private_data)
9009 : {
9010 0 : struct torture_printer_context *t =
9011 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data,
9012 : struct torture_printer_context);
9013 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9014 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9015 0 : uint32_t num_jobs = 8;
9016 : uint32_t *job_ids;
9017 : int i;
9018 0 : bool ret = true;
9019 : uint32_t count;
9020 : union spoolss_JobInfo *info;
9021 :
9022 0 : torture_assert(tctx,
9023 : test_PausePrinter(tctx, b, &t->handle),
9024 : "failed to pause printer");
9025 :
9026 0 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
9027 0 : for (i=0; i < num_jobs; i++) {
9028 0 : ret = test_DoPrintTest_add_one_job(tctx, b, &t->handle,
9029 : "TorturePrintJob",
9030 0 : &job_ids[i]);
9031 0 : torture_assert(tctx, ret, "failed to add print job");
9032 : }
9033 :
9034 0 : torture_assert(tctx,
9035 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9036 : &count, &info),
9037 : "EnumJobs level 1 failed");
9038 :
9039 0 : torture_assert_int_equal(tctx, count, num_jobs,
9040 : "unexpected number of jobs in queue");
9041 :
9042 0 : torture_assert(tctx,
9043 : test_printer_purge(tctx, b, &t->handle),
9044 : "failed to purge printer");
9045 :
9046 0 : torture_assert(tctx,
9047 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9048 : &count, &info),
9049 : "EnumJobs level 1 failed");
9050 :
9051 0 : torture_assert_int_equal(tctx, count, 0,
9052 : "unexpected number of jobs in queue");
9053 :
9054 0 : torture_assert(tctx,
9055 : test_ResumePrinter(tctx, b, &t->handle),
9056 : "failed to resume printer");
9057 :
9058 0 : return true;
9059 : }
9060 :
9061 0 : static bool test_printer_sd(struct torture_context *tctx,
9062 : void *private_data)
9063 : {
9064 0 : struct torture_printer_context *t =
9065 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9066 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9067 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9068 :
9069 0 : torture_assert(tctx,
9070 : test_PrinterInfo_SD(tctx, b, &t->handle),
9071 : "failed to test security descriptors");
9072 :
9073 0 : return true;
9074 : }
9075 :
9076 0 : static bool test_printer_dm(struct torture_context *tctx,
9077 : void *private_data)
9078 : {
9079 0 : struct torture_printer_context *t =
9080 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9081 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9082 :
9083 0 : torture_assert(tctx,
9084 : test_PrinterInfo_DevMode(tctx, p, &t->handle, t->info2.printername, t->devmode),
9085 : "failed to test devicemodes");
9086 :
9087 0 : return true;
9088 : }
9089 :
9090 0 : static bool test_printer_info_winreg(struct torture_context *tctx,
9091 : void *private_data)
9092 : {
9093 0 : struct torture_printer_context *t =
9094 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9095 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9096 :
9097 0 : torture_assert(tctx,
9098 : test_PrinterInfo_winreg(tctx, p, &t->handle, t->info2.printername),
9099 : "failed to test printer info winreg");
9100 :
9101 0 : return true;
9102 : }
9103 :
9104 0 : static bool test_printserver_info_winreg(struct torture_context *tctx,
9105 : void *private_data)
9106 : {
9107 0 : struct test_spoolss_context *t =
9108 0 : (struct test_spoolss_context *)talloc_get_type_abort(private_data, struct test_spoolss_context);
9109 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9110 :
9111 0 : torture_assert(tctx,
9112 : test_PrintserverInfo_winreg(tctx, p, &t->server_handle),
9113 : "failed to test printserver info winreg");
9114 :
9115 0 : return true;
9116 : }
9117 :
9118 :
9119 0 : static bool test_printer_change_id(struct torture_context *tctx,
9120 : void *private_data)
9121 : {
9122 0 : struct torture_printer_context *t =
9123 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9124 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9125 :
9126 0 : torture_assert(tctx,
9127 : test_ChangeID(tctx, p, &t->handle),
9128 : "failed to test change id");
9129 :
9130 0 : return true;
9131 : }
9132 :
9133 0 : static bool test_printer_keys(struct torture_context *tctx,
9134 : void *private_data)
9135 : {
9136 0 : struct torture_printer_context *t =
9137 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9138 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9139 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9140 :
9141 0 : torture_assert(tctx,
9142 : test_printer_all_keys(tctx, b, &t->handle),
9143 : "failed to test printer keys");
9144 :
9145 0 : return true;
9146 : }
9147 :
9148 0 : static bool test_printer_data_consistency(struct torture_context *tctx,
9149 : void *private_data)
9150 : {
9151 0 : struct torture_printer_context *t =
9152 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9153 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9154 :
9155 0 : torture_assert(tctx,
9156 : test_EnumPrinterData_consistency(tctx, p, &t->handle),
9157 : "failed to test printer data consistency");
9158 :
9159 0 : return true;
9160 : }
9161 :
9162 0 : static bool test_printer_data_keys(struct torture_context *tctx,
9163 : void *private_data)
9164 : {
9165 0 : struct torture_printer_context *t =
9166 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9167 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9168 :
9169 0 : torture_assert(tctx,
9170 : test_SetPrinterDataEx_keys(tctx, p, &t->handle),
9171 : "failed to test printer data keys");
9172 :
9173 0 : return true;
9174 : }
9175 :
9176 0 : static bool test_printer_data_values(struct torture_context *tctx,
9177 : void *private_data)
9178 : {
9179 0 : struct torture_printer_context *t =
9180 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9181 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9182 :
9183 0 : torture_assert(tctx,
9184 : test_SetPrinterDataEx_values(tctx, p, &t->handle),
9185 : "failed to test printer data values");
9186 :
9187 0 : return true;
9188 : }
9189 :
9190 0 : static bool test_printer_data_set(struct torture_context *tctx,
9191 : void *private_data)
9192 : {
9193 0 : struct torture_printer_context *t =
9194 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9195 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9196 :
9197 0 : torture_assert(tctx,
9198 : test_SetPrinterDataEx_matrix(tctx, p, &t->handle, t->info2.printername, NULL, NULL),
9199 : "failed to test printer data set");
9200 :
9201 0 : return true;
9202 : }
9203 :
9204 0 : static bool test_printer_data_winreg(struct torture_context *tctx,
9205 : void *private_data)
9206 : {
9207 0 : struct torture_printer_context *t =
9208 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9209 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9210 :
9211 0 : torture_assert(tctx,
9212 : test_PrinterData_winreg(tctx, p, &t->handle, t->info2.printername),
9213 : "failed to test printer data winreg");
9214 :
9215 0 : return true;
9216 : }
9217 :
9218 0 : static bool test_printer_data_dsspooler(struct torture_context *tctx,
9219 : void *private_data)
9220 : {
9221 0 : struct torture_printer_context *t =
9222 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9223 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9224 :
9225 0 : torture_assert(tctx,
9226 : test_PrinterData_DsSpooler(tctx, p, &t->handle, t->info2.printername),
9227 : "failed to test printer data winreg dsspooler");
9228 :
9229 0 : return true;
9230 : }
9231 :
9232 0 : static bool test_printer_ic(struct torture_context *tctx,
9233 : void *private_data)
9234 : {
9235 0 : struct torture_printer_context *t =
9236 0 : talloc_get_type_abort(private_data,
9237 : struct torture_printer_context);
9238 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9239 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9240 : struct policy_handle gdi_handle;
9241 :
9242 0 : if (torture_setting_bool(tctx, "samba3", false)) {
9243 0 : torture_skip(tctx, "skip printer information context tests against samba");
9244 : }
9245 :
9246 : {
9247 : struct spoolss_CreatePrinterIC r;
9248 : struct spoolss_DevmodeContainer devmode_ctr;
9249 :
9250 0 : ZERO_STRUCT(devmode_ctr);
9251 :
9252 0 : r.in.handle = &t->handle;
9253 0 : r.in.devmode_ctr = &devmode_ctr;
9254 0 : r.out.gdi_handle = &gdi_handle;
9255 :
9256 0 : torture_assert_ntstatus_ok(tctx,
9257 : dcerpc_spoolss_CreatePrinterIC_r(b, tctx, &r),
9258 : "CreatePrinterIC failed");
9259 0 : torture_assert_werr_ok(tctx, r.out.result,
9260 : "CreatePrinterIC failed");
9261 : }
9262 :
9263 : {
9264 : struct spoolss_PlayGDIScriptOnPrinterIC r;
9265 : DATA_BLOB in,out;
9266 : int i;
9267 0 : uint32_t num_fonts = 0;
9268 :
9269 0 : in = data_blob_string_const("");
9270 :
9271 0 : r.in.gdi_handle = &gdi_handle;
9272 0 : r.in.pIn = in.data;
9273 0 : r.in.cIn = in.length;
9274 0 : r.in.ul = 0;
9275 :
9276 0 : for (i = 0; i < 4; i++) {
9277 :
9278 0 : out = data_blob_talloc_zero(tctx, i);
9279 :
9280 0 : r.in.cOut = out.length;
9281 0 : r.out.pOut = out.data;
9282 :
9283 0 : torture_assert_ntstatus_ok(tctx,
9284 : dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r(b, tctx, &r),
9285 : "PlayGDIScriptOnPrinterIC failed");
9286 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_ENOUGH_MEMORY,
9287 : "PlayGDIScriptOnPrinterIC failed");
9288 : }
9289 :
9290 0 : out = data_blob_talloc_zero(tctx, 4);
9291 :
9292 0 : r.in.cOut = out.length;
9293 0 : r.out.pOut = out.data;
9294 :
9295 0 : torture_assert_ntstatus_ok(tctx,
9296 : dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r(b, tctx, &r),
9297 : "PlayGDIScriptOnPrinterIC failed");
9298 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9299 : "PlayGDIScriptOnPrinterIC failed");
9300 :
9301 : /* now we should have the required length, so retry with a
9302 : * buffer which is large enough to carry all font ids */
9303 :
9304 0 : num_fonts = IVAL(r.out.pOut, 0);
9305 :
9306 0 : torture_comment(tctx, "PlayGDIScriptOnPrinterIC gave font count of %d\n", num_fonts);
9307 :
9308 0 : out = data_blob_talloc_zero(tctx,
9309 0 : num_fonts * sizeof(struct UNIVERSAL_FONT_ID) + 4);
9310 :
9311 0 : r.in.cOut = out.length;
9312 0 : r.out.pOut = out.data;
9313 :
9314 0 : torture_assert_ntstatus_ok(tctx,
9315 : dcerpc_spoolss_PlayGDIScriptOnPrinterIC_r(b, tctx, &r),
9316 : "PlayGDIScriptOnPrinterIC failed");
9317 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9318 : "PlayGDIScriptOnPrinterIC failed");
9319 :
9320 : }
9321 :
9322 : {
9323 : struct spoolss_DeletePrinterIC r;
9324 :
9325 0 : r.in.gdi_handle = &gdi_handle;
9326 0 : r.out.gdi_handle = &gdi_handle;
9327 :
9328 0 : torture_assert_ntstatus_ok(tctx,
9329 : dcerpc_spoolss_DeletePrinterIC_r(b, tctx, &r),
9330 : "DeletePrinterIC failed");
9331 0 : torture_assert_werr_ok(tctx, r.out.result,
9332 : "DeletePrinterIC failed");
9333 :
9334 : }
9335 :
9336 0 : return true;
9337 : }
9338 :
9339 0 : static bool test_printer_bidi(struct torture_context *tctx,
9340 : void *private_data)
9341 : {
9342 0 : struct torture_printer_context *t =
9343 0 : talloc_get_type_abort(private_data,
9344 : struct torture_printer_context);
9345 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9346 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9347 : struct spoolss_SendRecvBidiData r;
9348 : struct RPC_BIDI_REQUEST_CONTAINER bidi_req;
9349 0 : struct RPC_BIDI_RESPONSE_CONTAINER *bidi_rep = NULL;
9350 :
9351 0 : if (torture_setting_bool(tctx, "samba3", false)) {
9352 0 : torture_skip(tctx, "skip printer bidirectional tests against samba");
9353 : }
9354 :
9355 0 : ZERO_STRUCT(bidi_req);
9356 :
9357 0 : r.in.hPrinter = t->handle;
9358 0 : r.in.pAction = "foobar";
9359 0 : r.in.pReqData = &bidi_req;
9360 0 : r.out.ppRespData = &bidi_rep;
9361 :
9362 0 : torture_assert_ntstatus_ok(tctx,
9363 : dcerpc_spoolss_SendRecvBidiData_r(b, tctx, &r),
9364 : "SendRecvBidiData failed");
9365 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
9366 : "SendRecvBidiData failed");
9367 :
9368 0 : if (!(t->info2.attributes & PRINTER_ATTRIBUTE_ENABLE_BIDI)) {
9369 0 : torture_skip(tctx, "skipping further tests as printer is not BIDI enabled");
9370 : }
9371 :
9372 0 : r.in.pAction = BIDI_ACTION_ENUM_SCHEMA;
9373 :
9374 0 : torture_assert_ntstatus_ok(tctx,
9375 : dcerpc_spoolss_SendRecvBidiData_r(b, tctx, &r),
9376 : "SendRecvBidiData failed");
9377 0 : torture_assert_werr_ok(tctx, r.out.result,
9378 : "SendRecvBidiData failed");
9379 :
9380 0 : return true;
9381 : }
9382 :
9383 0 : static bool test_printer_set_publish(struct torture_context *tctx,
9384 : struct dcerpc_binding_handle *b,
9385 : struct policy_handle *handle)
9386 : {
9387 : union spoolss_PrinterInfo info;
9388 : struct spoolss_SetPrinterInfo7 info7;
9389 : struct spoolss_SetPrinterInfoCtr info_ctr;
9390 : struct spoolss_DevmodeContainer devmode_ctr;
9391 : struct sec_desc_buf secdesc_ctr;
9392 :
9393 0 : info7.guid = "";
9394 0 : info7.action = DSPRINT_PUBLISH;
9395 :
9396 0 : ZERO_STRUCT(info_ctr);
9397 0 : ZERO_STRUCT(devmode_ctr);
9398 0 : ZERO_STRUCT(secdesc_ctr);
9399 0 : info_ctr.level = 7;
9400 0 : info_ctr.info.info7 = &info7;
9401 :
9402 0 : torture_assert(tctx,
9403 : test_SetPrinter(tctx, b, handle, &info_ctr,
9404 : &devmode_ctr, &secdesc_ctr, 0), "");
9405 :
9406 0 : torture_assert(tctx,
9407 : test_GetPrinter_level(tctx, b, handle, 2, &info),
9408 : "");
9409 0 : torture_assert(tctx,
9410 : (info.info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED),
9411 : "info2 publish flag not set");
9412 0 : torture_assert(tctx,
9413 : test_GetPrinter_level(tctx, b, handle, 7, &info),
9414 : "");
9415 0 : if (info.info7.action & DSPRINT_PENDING) {
9416 0 : torture_comment(tctx, "publish is pending\n");
9417 0 : torture_assert_int_equal(tctx,
9418 : info.info7.action,
9419 : (DSPRINT_PENDING | DSPRINT_PUBLISH),
9420 : "info7 publish flag not set");
9421 : } else {
9422 : struct GUID guid;
9423 : char *ref_guid;
9424 0 : torture_assert_int_equal(tctx,
9425 : info.info7.action,
9426 : DSPRINT_PUBLISH,
9427 : "info7 publish flag not set");
9428 :
9429 : /* GUID_from_string is able to parse both plain and
9430 : * curly-braced guids */
9431 0 : torture_assert_ntstatus_ok(tctx,
9432 : GUID_from_string(info.info7.guid,
9433 : &guid),
9434 : "invalid published printer GUID");
9435 :
9436 : /* Build reference GUID string */
9437 0 : ref_guid = GUID_string2(tctx, &guid);
9438 0 : torture_assert_not_null(tctx, ref_guid, "ENOMEM");
9439 0 : ref_guid = talloc_strdup_upper(tctx, ref_guid);
9440 0 : torture_assert_not_null(tctx, ref_guid, "ENOMEM");
9441 0 : torture_assert_str_equal(tctx, info.info7.guid, ref_guid,
9442 : "invalid GUID format");
9443 : }
9444 :
9445 0 : return true;
9446 : }
9447 :
9448 0 : static bool test_printer_set_unpublish(struct torture_context *tctx,
9449 : struct dcerpc_binding_handle *b,
9450 : struct policy_handle *handle)
9451 : {
9452 : union spoolss_PrinterInfo info;
9453 : struct spoolss_SetPrinterInfo7 info7;
9454 : struct spoolss_SetPrinterInfoCtr info_ctr;
9455 : struct spoolss_DevmodeContainer devmode_ctr;
9456 : struct sec_desc_buf secdesc_ctr;
9457 :
9458 0 : info7.action = DSPRINT_UNPUBLISH;
9459 0 : info7.guid = "";
9460 :
9461 0 : ZERO_STRUCT(info_ctr);
9462 0 : ZERO_STRUCT(devmode_ctr);
9463 0 : ZERO_STRUCT(secdesc_ctr);
9464 0 : info_ctr.level = 7;
9465 0 : info_ctr.info.info7 = &info7;
9466 :
9467 0 : torture_assert(tctx,
9468 : test_SetPrinter(tctx, b, handle, &info_ctr,
9469 : &devmode_ctr, &secdesc_ctr, 0), "");
9470 :
9471 0 : torture_assert(tctx,
9472 : test_GetPrinter_level(tctx, b, handle, 2, &info),
9473 : "");
9474 0 : torture_assert(tctx,
9475 : !(info.info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED),
9476 : "info2 publish flag still set");
9477 0 : torture_assert(tctx,
9478 : test_GetPrinter_level(tctx, b, handle, 7, &info),
9479 : "");
9480 :
9481 0 : if (info.info7.action & DSPRINT_PENDING) {
9482 : struct GUID guid;
9483 0 : torture_comment(tctx, "unpublish is pending\n");
9484 0 : torture_assert_int_equal(tctx,
9485 : info.info7.action,
9486 : (DSPRINT_PENDING | DSPRINT_UNPUBLISH),
9487 : "info7 unpublish flag not set");
9488 0 : torture_assert_ntstatus_ok(tctx,
9489 : GUID_from_string(info.info7.guid,
9490 : &guid),
9491 : "invalid printer GUID");
9492 : } else {
9493 0 : torture_assert_int_equal(tctx,
9494 : info.info7.action, DSPRINT_UNPUBLISH,
9495 : "info7 unpublish flag not set");
9496 : }
9497 :
9498 0 : return true;
9499 : }
9500 :
9501 0 : static bool test_printer_publish_toggle(struct torture_context *tctx,
9502 : void *private_data)
9503 : {
9504 0 : struct torture_printer_context *t =
9505 0 : talloc_get_type_abort(private_data,
9506 : struct torture_printer_context);
9507 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9508 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9509 0 : struct policy_handle *handle = &t->handle;
9510 : union spoolss_PrinterInfo info7;
9511 : union spoolss_PrinterInfo info2;
9512 :
9513 : /* check publish status via level 7 and level 2 */
9514 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 7, &info7),
9515 : "");
9516 0 : torture_assert(tctx, test_GetPrinter_level(tctx, b, handle, 2, &info2),
9517 : "");
9518 :
9519 0 : if (info2.info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
9520 0 : torture_assert_int_equal(tctx,
9521 : info7.info7.action, DSPRINT_PUBLISH,
9522 : "info7 publish flag not set");
9523 0 : torture_assert(tctx, test_printer_set_unpublish(tctx, b, handle), "");
9524 0 : torture_assert(tctx, test_printer_set_publish(tctx, b, handle), "");
9525 : } else {
9526 0 : torture_assert_int_equal(tctx,
9527 : info7.info7.action, DSPRINT_UNPUBLISH,
9528 : "info7 unpublish flag not set");
9529 0 : torture_assert(tctx, test_printer_set_publish(tctx, b, handle), "");
9530 0 : torture_assert(tctx, test_printer_set_unpublish(tctx, b, handle), "");
9531 : }
9532 :
9533 0 : return true;
9534 : }
9535 :
9536 0 : static bool test_driver_info_winreg(struct torture_context *tctx,
9537 : void *private_data)
9538 : {
9539 0 : struct torture_printer_context *t =
9540 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9541 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9542 0 : const char *driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
9543 :
9544 0 : if (!t->have_driver) {
9545 0 : torture_skip(tctx, "skipping driver info winreg test as we don't have a driver");
9546 : }
9547 :
9548 0 : torture_assert(tctx,
9549 : test_DriverInfo_winreg(tctx, p, &t->handle, t->info2.printername, driver_name, t->driver.remote.environment, 3),
9550 : "failed to test driver info winreg");
9551 :
9552 0 : return true;
9553 : }
9554 :
9555 0 : static bool test_print_job_enum(struct torture_context *tctx,
9556 : void *private_data)
9557 : {
9558 0 : struct torture_printer_context *t =
9559 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9560 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9561 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9562 0 : bool ret = true;
9563 0 : uint32_t num_jobs = 8;
9564 : uint32_t *job_ids;
9565 : int i;
9566 0 : union spoolss_JobInfo *info = NULL;
9567 : uint32_t count;
9568 :
9569 0 : torture_assert(tctx,
9570 : test_PausePrinter(tctx, b, &t->handle),
9571 : "failed to pause printer");
9572 :
9573 : /* purge in case of any jobs from previous tests */
9574 0 : torture_assert(tctx,
9575 : test_printer_purge(tctx, b, &t->handle),
9576 : "failed to purge printer");
9577 :
9578 : /* enum before jobs, valid level */
9579 0 : torture_assert(tctx,
9580 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9581 : &count, &info),
9582 : "EnumJobs with valid level");
9583 0 : torture_assert_int_equal(tctx, count, 0, "EnumJobs count");
9584 0 : torture_assert(tctx,
9585 : test_EnumJobs_args(tctx, b, &t->handle, 2, WERR_OK,
9586 : &count, &info),
9587 : "EnumJobs with valid level");
9588 0 : torture_assert_int_equal(tctx, count, 0, "EnumJobs count");
9589 : /* enum before jobs, invalid level - expect failure */
9590 0 : torture_assert(tctx,
9591 : test_EnumJobs_args(tctx, b, &t->handle, 100,
9592 : WERR_INVALID_LEVEL,
9593 : &count, &info),
9594 : "EnumJobs with invalid level");
9595 :
9596 0 : job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
9597 :
9598 0 : for (i = 0; i < num_jobs; i++) {
9599 0 : ret = test_DoPrintTest_add_one_job(tctx, b, &t->handle,
9600 : "TorturePrintJob",
9601 0 : &job_ids[i]);
9602 0 : torture_assert(tctx, ret, "failed to add print job");
9603 : }
9604 :
9605 : /* enum after jobs, valid level */
9606 0 : torture_assert(tctx,
9607 : test_EnumJobs_args(tctx, b, &t->handle, 1, WERR_OK,
9608 : &count, &info),
9609 : "EnumJobs with valid level");
9610 0 : torture_assert_int_equal(tctx, count, num_jobs, "EnumJobs count");
9611 0 : torture_assert(tctx,
9612 : test_EnumJobs_args(tctx, b, &t->handle, 2, WERR_OK,
9613 : &count, &info),
9614 : "EnumJobs with valid level");
9615 0 : torture_assert_int_equal(tctx, count, num_jobs, "EnumJobs count");
9616 : /* enum after jobs, invalid level - expect failure */
9617 0 : torture_assert(tctx,
9618 : test_EnumJobs_args(tctx, b, &t->handle, 100,
9619 : WERR_INVALID_LEVEL,
9620 : &count, &info),
9621 : "EnumJobs with invalid level");
9622 :
9623 0 : for (i = 0; i < num_jobs; i++) {
9624 0 : test_SetJob(tctx, b, &t->handle, job_ids[i], NULL,
9625 : SPOOLSS_JOB_CONTROL_DELETE);
9626 : }
9627 :
9628 0 : torture_assert(tctx,
9629 : test_ResumePrinter(tctx, b, &t->handle),
9630 : "failed to resume printer");
9631 :
9632 0 : return true;
9633 : }
9634 :
9635 0 : static bool test_printer_log_jobinfo(struct torture_context *tctx,
9636 : void *private_data)
9637 : {
9638 0 : struct torture_printer_context *t =
9639 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9640 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9641 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9642 : struct spoolss_BranchOfficeJobDataContainer info;
9643 : int i;
9644 :
9645 : struct spoolss_LogJobInfoForBranchOffice r;
9646 :
9647 0 : torture_comment(tctx, "Testing LogJobInfoForBranchOffice\n");
9648 :
9649 0 : info.cJobDataEntries = 0;
9650 0 : info.JobData = NULL;
9651 :
9652 0 : r.in.hPrinter = &t->handle;
9653 0 : r.in.pBranchOfficeJobDataContainer = &info;
9654 :
9655 0 : torture_assert_ntstatus_ok(tctx,
9656 : dcerpc_spoolss_LogJobInfoForBranchOffice_r(b, tctx, &r),
9657 : "LogJobInfoForBranchOffice failed");
9658 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
9659 : "LogJobInfoForBranchOffice failed");
9660 :
9661 0 : info.cJobDataEntries = 1;
9662 0 : info.JobData = talloc_zero_array(tctx, struct spoolss_BranchOfficeJobData, info.cJobDataEntries);
9663 :
9664 0 : info.JobData[0].eEventType = kLogOfflineFileFull;
9665 0 : info.JobData[0].JobId = 42;
9666 0 : info.JobData[0].JobInfo.LogOfflineFileFull.pMachineName = talloc_strdup(tctx, "mthelena");
9667 :
9668 0 : torture_assert_ntstatus_ok(tctx,
9669 : dcerpc_spoolss_LogJobInfoForBranchOffice_r(b, tctx, &r),
9670 : "LogJobInfoForBranchOffice failed");
9671 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9672 : "LogJobInfoForBranchOffice failed");
9673 :
9674 0 : info.cJobDataEntries = 42;
9675 0 : info.JobData = talloc_zero_array(tctx, struct spoolss_BranchOfficeJobData, info.cJobDataEntries);
9676 :
9677 0 : for (i=0; i < info.cJobDataEntries; i++) {
9678 0 : info.JobData[i].eEventType = kLogOfflineFileFull;
9679 0 : info.JobData[i].JobId = i;
9680 0 : info.JobData[i].JobInfo.LogOfflineFileFull.pMachineName = talloc_asprintf(tctx, "torture_%d", i);
9681 : }
9682 :
9683 0 : torture_assert_ntstatus_ok(tctx,
9684 : dcerpc_spoolss_LogJobInfoForBranchOffice_r(b, tctx, &r),
9685 : "LogJobInfoForBranchOffice failed");
9686 0 : torture_assert_werr_equal(tctx, r.out.result, WERR_OK,
9687 : "LogJobInfoForBranchOffice failed");
9688 :
9689 0 : return true;
9690 : }
9691 :
9692 0 : static bool test_printer_os_versions(struct torture_context *tctx,
9693 : void *private_data)
9694 : {
9695 0 : struct torture_printer_context *t =
9696 0 : (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
9697 0 : struct dcerpc_pipe *p = t->spoolss_pipe;
9698 0 : struct dcerpc_binding_handle *b = p->binding_handle;
9699 : union spoolss_PrinterInfo info;
9700 : DATA_BLOB blob;
9701 : uint8_t *data;
9702 : uint32_t length;
9703 : struct spoolss_OSVersion osversion;
9704 : uint8_t os_major, os_minor;
9705 : uint16_t os_build;
9706 : struct policy_handle server_handle;
9707 :
9708 0 : torture_comment(tctx, "Testing OSVersion vs. PRINTER_INFO_STRESS\n");
9709 :
9710 0 : torture_assert(tctx,
9711 : test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
9712 : "failed to get level 0 printer info");
9713 :
9714 0 : torture_assert(tctx,
9715 : test_OpenPrinter_server(tctx, p, &server_handle),
9716 : "failed to open printserver");
9717 :
9718 0 : torture_assert(tctx,
9719 : test_GetPrinterData_checktype(tctx, b, &server_handle, "OSVersion",
9720 : NULL, NULL, &data, &length),
9721 : "failed to fetch OSVersion printer data");
9722 :
9723 0 : test_ClosePrinter(tctx, b, &server_handle);
9724 :
9725 0 : blob = data_blob_const(data, length);
9726 :
9727 0 : torture_assert_ndr_success(tctx,
9728 : ndr_pull_struct_blob(&blob, tctx, &osversion,
9729 : (ndr_pull_flags_fn_t)ndr_pull_spoolss_OSVersion),
9730 : "failed to pull OSVersion");
9731 :
9732 0 : os_major = CVAL(&info.info0.version, 0);
9733 0 : os_minor = CVAL(&info.info0.version, 1);
9734 0 : os_build = SVAL(&info.info0.version, 2);
9735 :
9736 0 : torture_assert_int_equal(tctx, os_major, osversion.major, "major");
9737 0 : torture_assert_int_equal(tctx, os_minor, osversion.minor, "minor");
9738 0 : torture_assert_int_equal(tctx, os_build, osversion.build, "build");
9739 :
9740 0 : return true;
9741 : }
9742 :
9743 :
9744 1928 : void torture_tcase_printer(struct torture_tcase *tcase)
9745 : {
9746 1928 : torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter_wrap);
9747 1928 : torture_tcase_add_simple_test(tcase, "csetprinter", test_csetprinter);
9748 1928 : torture_tcase_add_simple_test(tcase, "print_test", test_print_test);
9749 1928 : torture_tcase_add_simple_test(tcase, "print_test_extended", test_print_test_extended);
9750 1928 : torture_tcase_add_simple_test(tcase, "print_test_smbd", test_print_test_smbd);
9751 1928 : torture_tcase_add_simple_test(tcase, "print_test_properties", test_print_test_properties);
9752 1928 : torture_tcase_add_simple_test(tcase, "print_test_purge", test_print_test_purge);
9753 1928 : torture_tcase_add_simple_test(tcase, "printer_info", test_printer_info);
9754 1928 : torture_tcase_add_simple_test(tcase, "sd", test_printer_sd);
9755 1928 : torture_tcase_add_simple_test(tcase, "dm", test_printer_dm);
9756 1928 : torture_tcase_add_simple_test(tcase, "printer_info_winreg", test_printer_info_winreg);
9757 1928 : torture_tcase_add_simple_test(tcase, "change_id", test_printer_change_id);
9758 1928 : torture_tcase_add_simple_test(tcase, "keys", test_printer_keys);
9759 1928 : torture_tcase_add_simple_test(tcase, "printerdata_consistency", test_printer_data_consistency);
9760 1928 : torture_tcase_add_simple_test(tcase, "printerdata_keys", test_printer_data_keys);
9761 1928 : torture_tcase_add_simple_test(tcase, "printerdata_values", test_printer_data_values);
9762 1928 : torture_tcase_add_simple_test(tcase, "printerdata_set", test_printer_data_set);
9763 1928 : torture_tcase_add_simple_test(tcase, "printerdata_winreg", test_printer_data_winreg);
9764 1928 : torture_tcase_add_simple_test(tcase, "printerdata_dsspooler", test_printer_data_dsspooler);
9765 1928 : torture_tcase_add_simple_test(tcase, "driver_info_winreg", test_driver_info_winreg);
9766 1928 : torture_tcase_add_simple_test(tcase, "printer_rename", test_printer_rename);
9767 1928 : torture_tcase_add_simple_test(tcase, "printer_ic", test_printer_ic);
9768 1928 : torture_tcase_add_simple_test(tcase, "bidi", test_printer_bidi);
9769 1928 : torture_tcase_add_simple_test(tcase, "publish_toggle",
9770 : test_printer_publish_toggle);
9771 1928 : torture_tcase_add_simple_test(tcase, "print_job_enum", test_print_job_enum);
9772 1928 : torture_tcase_add_simple_test(tcase, "log_jobinfo", test_printer_log_jobinfo);
9773 1928 : torture_tcase_add_simple_test(tcase, "os_versions", test_printer_os_versions);
9774 1928 : }
9775 :
9776 964 : struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
9777 : {
9778 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "printer");
9779 : struct torture_tcase *tcase;
9780 :
9781 964 : tcase = torture_suite_add_tcase(suite, "addprinter");
9782 :
9783 964 : torture_tcase_set_fixture(tcase,
9784 : torture_rpc_spoolss_printer_setup,
9785 : torture_rpc_spoolss_printer_teardown);
9786 :
9787 964 : torture_tcase_printer(tcase);
9788 :
9789 964 : tcase = torture_suite_add_tcase(suite, "addprinterex");
9790 :
9791 964 : torture_tcase_set_fixture(tcase,
9792 : torture_rpc_spoolss_printerex_setup,
9793 : torture_rpc_spoolss_printer_teardown);
9794 :
9795 964 : torture_tcase_printer(tcase);
9796 :
9797 964 : tcase = torture_suite_add_tcase(suite, "addprinterwkn");
9798 :
9799 964 : torture_tcase_set_fixture(tcase,
9800 : torture_rpc_spoolss_printerwkn_setup,
9801 : torture_rpc_spoolss_printer_teardown);
9802 :
9803 964 : tcase = torture_suite_add_tcase(suite, "addprinterexwkn");
9804 :
9805 964 : torture_tcase_set_fixture(tcase,
9806 : torture_rpc_spoolss_printerexwkn_setup,
9807 : torture_rpc_spoolss_printer_teardown);
9808 :
9809 : #if 0
9810 : /* test is not correct */
9811 : tcase = torture_suite_add_tcase(suite, "addprinterdm");
9812 :
9813 : torture_tcase_set_fixture(tcase,
9814 : torture_rpc_spoolss_printerdm_setup,
9815 : torture_rpc_spoolss_printer_teardown);
9816 :
9817 : torture_tcase_printer(tcase);
9818 : #endif
9819 964 : return suite;
9820 : }
9821 :
9822 964 : struct torture_suite *torture_rpc_spoolss(TALLOC_CTX *mem_ctx)
9823 : {
9824 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss");
9825 964 : struct torture_tcase *tcase = torture_suite_add_tcase(suite, "printserver");
9826 :
9827 964 : torture_tcase_set_fixture(tcase,
9828 : torture_rpc_spoolss_setup,
9829 : torture_rpc_spoolss_teardown);
9830 :
9831 964 : torture_tcase_add_simple_test(tcase, "openprinter_badnamelist", test_OpenPrinter_badname_list);
9832 964 : torture_tcase_add_simple_test(tcase, "printer_data_list", test_GetPrinterData_list);
9833 964 : torture_tcase_add_simple_test(tcase, "enum_forms", test_PrintServer_EnumForms);
9834 964 : torture_tcase_add_simple_test(tcase, "forms", test_PrintServer_Forms);
9835 964 : torture_tcase_add_simple_test(tcase, "forms_winreg", test_PrintServer_Forms_Winreg);
9836 964 : torture_tcase_add_simple_test(tcase, "enum_ports", test_EnumPorts);
9837 964 : torture_tcase_add_simple_test(tcase, "add_port", test_AddPort);
9838 964 : torture_tcase_add_simple_test(tcase, "get_printer_driver_directory", test_GetPrinterDriverDirectory);
9839 964 : torture_tcase_add_simple_test(tcase, "get_print_processor_directory", test_GetPrintProcessorDirectory);
9840 964 : torture_tcase_add_simple_test(tcase, "enum_printer_drivers", test_EnumPrinterDrivers);
9841 964 : torture_tcase_add_simple_test(tcase, "enum_monitors", test_EnumMonitors);
9842 964 : torture_tcase_add_simple_test(tcase, "enum_print_processors", test_EnumPrintProcessors);
9843 964 : torture_tcase_add_simple_test(tcase, "print_processors_winreg", test_print_processors_winreg);
9844 964 : torture_tcase_add_simple_test(tcase, "add_processor", test_add_print_processor);
9845 964 : torture_tcase_add_simple_test(tcase, "enum_printprocdata", test_EnumPrintProcessorDataTypes);
9846 964 : torture_tcase_add_simple_test(tcase, "enum_printers", test_EnumPrinters);
9847 964 : torture_tcase_add_simple_test(tcase, "enum_ports_old", test_EnumPorts_old);
9848 964 : torture_tcase_add_simple_test(tcase, "enum_printers_old", test_EnumPrinters_old);
9849 964 : torture_tcase_add_simple_test(tcase, "enum_printers_servername", test_EnumPrinters_servername);
9850 964 : torture_tcase_add_simple_test(tcase, "enum_printer_drivers_old", test_EnumPrinterDrivers_old);
9851 964 : torture_tcase_add_simple_test(tcase, "architecture_buffer", test_architecture_buffer);
9852 964 : torture_tcase_add_simple_test(tcase, "get_core_printer_drivers", test_get_core_printer_drivers);
9853 964 : torture_tcase_add_simple_test(tcase, "get_printer_driver_package_path", test_get_printer_driver_package_path);
9854 964 : torture_tcase_add_simple_test(tcase, "get_printer", test_get_printer_printserverhandle);
9855 964 : torture_tcase_add_simple_test(tcase, "set_printer", test_set_printer_printserverhandle);
9856 964 : torture_tcase_add_simple_test(tcase, "printserver_info_winreg", test_printserver_info_winreg);
9857 964 : torture_tcase_add_simple_test(tcase, "addpermachineconnection", test_addpermachineconnection);
9858 :
9859 964 : torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
9860 :
9861 964 : return suite;
9862 : }
9863 :
9864 0 : static bool test_GetPrinterDriverDirectory_getdir(struct torture_context *tctx,
9865 : struct dcerpc_binding_handle *b,
9866 : const char *server,
9867 : const char *environment,
9868 : const char **dir_p)
9869 : {
9870 : struct spoolss_GetPrinterDriverDirectory r;
9871 : uint32_t needed;
9872 :
9873 0 : r.in.server = server;
9874 0 : r.in.environment = environment;
9875 0 : r.in.level = 1;
9876 0 : r.in.buffer = NULL;
9877 0 : r.in.offered = 0;
9878 0 : r.out.needed = &needed;
9879 :
9880 0 : torture_assert_ntstatus_ok(tctx,
9881 : dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r),
9882 : "failed to query driver directory");
9883 :
9884 0 : if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
9885 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
9886 0 : r.in.buffer = &blob;
9887 0 : r.in.offered = needed;
9888 :
9889 0 : torture_assert_ntstatus_ok(tctx,
9890 : dcerpc_spoolss_GetPrinterDriverDirectory_r(b, tctx, &r),
9891 : "failed to query driver directory");
9892 : }
9893 :
9894 0 : torture_assert_werr_ok(tctx, r.out.result,
9895 : "failed to query driver directory");
9896 :
9897 0 : if (dir_p) {
9898 0 : *dir_p = r.out.info->info1.directory_name;
9899 : }
9900 :
9901 0 : return true;
9902 : }
9903 :
9904 0 : static const char *get_driver_from_info(struct spoolss_AddDriverInfoCtr *info_ctr)
9905 : {
9906 0 : if (info_ctr == NULL) {
9907 0 : return NULL;
9908 : }
9909 :
9910 0 : switch (info_ctr->level) {
9911 0 : case 1:
9912 0 : return info_ctr->info.info1->driver_name;
9913 0 : case 2:
9914 0 : return info_ctr->info.info2->driver_name;
9915 0 : case 3:
9916 0 : return info_ctr->info.info3->driver_name;
9917 0 : case 4:
9918 0 : return info_ctr->info.info4->driver_name;
9919 0 : case 6:
9920 0 : return info_ctr->info.info6->driver_name;
9921 0 : case 8:
9922 0 : return info_ctr->info.info8->driver_name;
9923 0 : default:
9924 0 : return NULL;
9925 : }
9926 : }
9927 :
9928 0 : static const char *get_environment_from_info(struct spoolss_AddDriverInfoCtr *info_ctr)
9929 : {
9930 0 : if (info_ctr == NULL) {
9931 0 : return NULL;
9932 : }
9933 :
9934 0 : switch (info_ctr->level) {
9935 0 : case 2:
9936 0 : return info_ctr->info.info2->architecture;
9937 0 : case 3:
9938 0 : return info_ctr->info.info3->architecture;
9939 0 : case 4:
9940 0 : return info_ctr->info.info4->architecture;
9941 0 : case 6:
9942 0 : return info_ctr->info.info6->architecture;
9943 0 : case 8:
9944 0 : return info_ctr->info.info8->architecture;
9945 0 : default:
9946 0 : return NULL;
9947 : }
9948 : }
9949 :
9950 :
9951 0 : static bool test_AddPrinterDriver_exp(struct torture_context *tctx,
9952 : struct dcerpc_binding_handle *b,
9953 : const char *servername,
9954 : struct spoolss_AddDriverInfoCtr *info_ctr,
9955 : WERROR expected_result)
9956 : {
9957 : struct spoolss_AddPrinterDriver r;
9958 0 : const char *drivername = get_driver_from_info(info_ctr);
9959 0 : const char *environment = get_environment_from_info(info_ctr);
9960 :
9961 0 : r.in.servername = servername;
9962 0 : r.in.info_ctr = info_ctr;
9963 :
9964 0 : torture_comment(tctx, "Testing AddPrinterDriver(%s) level: %d, environment: '%s'\n",
9965 : drivername, info_ctr->level, environment);
9966 :
9967 0 : torture_assert_ntstatus_ok(tctx,
9968 : dcerpc_spoolss_AddPrinterDriver_r(b, tctx, &r),
9969 : "spoolss_AddPrinterDriver failed");
9970 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
9971 : "spoolss_AddPrinterDriver failed with unexpected result");
9972 :
9973 0 : return true;
9974 :
9975 : }
9976 :
9977 0 : static bool test_AddPrinterDriverEx_exp(struct torture_context *tctx,
9978 : struct dcerpc_binding_handle *b,
9979 : const char *servername,
9980 : struct spoolss_AddDriverInfoCtr *info_ctr,
9981 : uint32_t flags,
9982 : WERROR expected_result)
9983 : {
9984 : struct spoolss_AddPrinterDriverEx r;
9985 0 : const char *drivername = get_driver_from_info(info_ctr);
9986 0 : const char *environment = get_environment_from_info(info_ctr);
9987 :
9988 0 : r.in.servername = servername;
9989 0 : r.in.info_ctr = info_ctr;
9990 0 : r.in.flags = flags;
9991 :
9992 0 : torture_comment(tctx, "Testing AddPrinterDriverEx(%s) level: %d, environment: '%s'\n",
9993 : drivername, info_ctr->level, environment);
9994 :
9995 0 : torture_assert_ntstatus_ok(tctx,
9996 : dcerpc_spoolss_AddPrinterDriverEx_r(b, tctx, &r),
9997 : "AddPrinterDriverEx failed");
9998 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
9999 : "AddPrinterDriverEx failed with unexpected result");
10000 :
10001 0 : return true;
10002 : }
10003 :
10004 : #define ASSERT_DRIVER_PATH(tctx, path, driver_dir, cmt) \
10005 : if (path && strlen(path)) {\
10006 : torture_assert_strn_equal(tctx, path, driver_dir, strlen(driver_dir), cmt); \
10007 : }
10008 :
10009 0 : static bool test_AddPrinterDriver_args_level_1(struct torture_context *tctx,
10010 : struct dcerpc_binding_handle *b,
10011 : const char *server_name,
10012 : struct spoolss_AddDriverInfo8 *r,
10013 : uint32_t flags,
10014 : bool ex,
10015 : const char *remote_driver_dir)
10016 : {
10017 : struct spoolss_AddDriverInfoCtr info_ctr;
10018 : struct spoolss_AddDriverInfo1 info1;
10019 :
10020 0 : ZERO_STRUCT(info1);
10021 :
10022 0 : info_ctr.level = 1;
10023 0 : info_ctr.info.info1 = &info1;
10024 :
10025 0 : if (ex) {
10026 0 : torture_assert(tctx,
10027 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_LEVEL),
10028 : "failed to test AddPrinterDriverEx level 1");
10029 : } else {
10030 0 : torture_assert(tctx,
10031 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10032 : "failed to test AddPrinterDriver level 1");
10033 : }
10034 :
10035 0 : info1.driver_name = r->driver_name;
10036 :
10037 0 : if (ex) {
10038 0 : torture_assert(tctx,
10039 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_LEVEL),
10040 : "failed to test AddPrinterDriverEx level 1");
10041 : } else {
10042 0 : torture_assert(tctx,
10043 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10044 : "failed to test AddPrinterDriver level 1");
10045 : }
10046 :
10047 0 : return true;
10048 : }
10049 :
10050 0 : static bool test_AddPrinterDriver_args_level_2(struct torture_context *tctx,
10051 : struct dcerpc_binding_handle *b,
10052 : const char *server_name,
10053 : struct spoolss_AddDriverInfo8 *r,
10054 : uint32_t flags,
10055 : bool ex,
10056 : const char *remote_driver_dir)
10057 : {
10058 : struct spoolss_AddDriverInfoCtr info_ctr;
10059 : struct spoolss_AddDriverInfo2 info2;
10060 : union spoolss_DriverInfo info;
10061 :
10062 0 : ZERO_STRUCT(info2);
10063 :
10064 0 : info_ctr.level = 2;
10065 0 : info_ctr.info.info2 = &info2;
10066 :
10067 0 : if (ex) {
10068 0 : torture_assert(tctx,
10069 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10070 : "failed to test AddPrinterDriverEx level 2");
10071 : } else {
10072 0 : torture_assert(tctx,
10073 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10074 : "failed to test AddPrinterDriver level 2");
10075 : }
10076 :
10077 0 : info2.driver_name = r->driver_name;
10078 :
10079 0 : if (ex) {
10080 0 : torture_assert(tctx,
10081 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10082 : "failed to test AddPrinterDriverEx level 2");
10083 : } else {
10084 0 : torture_assert(tctx,
10085 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10086 : "failed to test AddPrinterDriver level 2");
10087 : }
10088 :
10089 0 : info2.version = r->version;
10090 :
10091 0 : if (ex) {
10092 0 : torture_assert(tctx,
10093 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10094 : "failed to test AddPrinterDriverEx level 2");
10095 : } else {
10096 0 : torture_assert(tctx,
10097 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10098 : "failed to test AddPrinterDriver level 2");
10099 : }
10100 :
10101 0 : info2.architecture = r->architecture;
10102 :
10103 0 : if (ex) {
10104 0 : torture_assert(tctx,
10105 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10106 : "failed to test AddPrinterDriverEx level 2");
10107 : } else {
10108 0 : torture_assert(tctx,
10109 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10110 : "failed to test AddPrinterDriver level 2");
10111 : }
10112 :
10113 0 : info2.driver_path = r->driver_path;
10114 :
10115 0 : if (ex) {
10116 0 : torture_assert(tctx,
10117 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10118 : "failed to test AddPrinterDriverEx level 2");
10119 : } else {
10120 0 : torture_assert(tctx,
10121 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10122 : "failed to test AddPrinterDriver level 2");
10123 : }
10124 :
10125 0 : info2.data_file = r->data_file;
10126 :
10127 0 : if (ex) {
10128 0 : torture_assert(tctx,
10129 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_INVALID_PARAMETER),
10130 : "failed to test AddPrinterDriverEx level 2");
10131 : } else {
10132 0 : torture_assert(tctx,
10133 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_PARAMETER),
10134 : "failed to test AddPrinterDriver level 2");
10135 : }
10136 :
10137 0 : info2.config_file = r->config_file;
10138 :
10139 0 : if (ex) {
10140 0 : torture_assert(tctx,
10141 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, 0, WERR_INVALID_PARAMETER),
10142 : "failed to test AddPrinterDriverEx");
10143 : }
10144 :
10145 0 : if (ex) {
10146 0 : torture_assert(tctx,
10147 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10148 : "failed to test AddPrinterDriverEx level 2");
10149 : } else {
10150 0 : torture_assert(tctx,
10151 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
10152 : "failed to test AddPrinterDriver level 2");
10153 : }
10154 :
10155 0 : torture_assert(tctx,
10156 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 2, r->driver_name, &info),
10157 : "failed to find added printer driver");
10158 :
10159 0 : if (remote_driver_dir) {
10160 0 : ASSERT_DRIVER_PATH(tctx, info.info2.driver_path, remote_driver_dir, "unexpected path");
10161 0 : ASSERT_DRIVER_PATH(tctx, info.info2.data_file, remote_driver_dir, "unexpected path");
10162 0 : ASSERT_DRIVER_PATH(tctx, info.info2.config_file, remote_driver_dir, "unexpected path");
10163 : }
10164 :
10165 0 : return true;
10166 : }
10167 :
10168 0 : static bool test_AddPrinterDriver_args_level_3(struct torture_context *tctx,
10169 : struct dcerpc_binding_handle *b,
10170 : const char *server_name,
10171 : struct spoolss_AddDriverInfo8 *r,
10172 : uint32_t flags,
10173 : bool ex,
10174 : const char *remote_driver_dir)
10175 : {
10176 : struct spoolss_AddDriverInfoCtr info_ctr;
10177 : struct spoolss_AddDriverInfo3 info3;
10178 : union spoolss_DriverInfo info;
10179 :
10180 0 : info3.driver_name = r->driver_name;
10181 0 : info3.version = r->version;
10182 0 : info3.architecture = r->architecture;
10183 0 : info3.driver_path = r->driver_path;
10184 0 : info3.data_file = r->data_file;
10185 0 : info3.config_file = r->config_file;
10186 0 : info3.help_file = r->help_file;
10187 0 : info3.monitor_name = r->monitor_name;
10188 0 : info3.default_datatype = r->default_datatype;
10189 0 : info3._ndr_size_dependent_files = r->_ndr_size_dependent_files;
10190 0 : info3.dependent_files = r->dependent_files;
10191 :
10192 0 : info_ctr.level = 3;
10193 0 : info_ctr.info.info3 = &info3;
10194 :
10195 0 : if (ex) {
10196 0 : torture_assert(tctx,
10197 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10198 : "failed to test AddPrinterDriverEx level 3");
10199 : } else {
10200 0 : torture_assert(tctx,
10201 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
10202 : "failed to test AddPrinterDriver level 3");
10203 : }
10204 :
10205 0 : torture_assert(tctx,
10206 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 3, r->driver_name, &info),
10207 : "failed to find added printer driver");
10208 :
10209 0 : if (remote_driver_dir) {
10210 : int i;
10211 0 : ASSERT_DRIVER_PATH(tctx, info.info3.driver_path, remote_driver_dir, "unexpected path");
10212 0 : ASSERT_DRIVER_PATH(tctx, info.info3.data_file, remote_driver_dir, "unexpected path");
10213 0 : ASSERT_DRIVER_PATH(tctx, info.info3.config_file, remote_driver_dir, "unexpected path");
10214 0 : ASSERT_DRIVER_PATH(tctx, info.info3.help_file, remote_driver_dir, "unexpected path");
10215 0 : for (i=0; info.info3.dependent_files && info.info3.dependent_files[i] != NULL; i++) {
10216 0 : ASSERT_DRIVER_PATH(tctx, info.info3.dependent_files[i], remote_driver_dir, "unexpected path");
10217 : }
10218 : }
10219 :
10220 0 : return true;
10221 : }
10222 :
10223 0 : static bool test_AddPrinterDriver_args_level_4(struct torture_context *tctx,
10224 : struct dcerpc_binding_handle *b,
10225 : const char *server_name,
10226 : struct spoolss_AddDriverInfo8 *r,
10227 : uint32_t flags,
10228 : bool ex,
10229 : const char *remote_driver_dir)
10230 : {
10231 : struct spoolss_AddDriverInfoCtr info_ctr;
10232 : struct spoolss_AddDriverInfo4 info4;
10233 : union spoolss_DriverInfo info;
10234 :
10235 0 : info4.version = r->version;
10236 0 : info4.driver_name = r->driver_name;
10237 0 : info4.architecture = r->architecture;
10238 0 : info4.driver_path = r->driver_path;
10239 0 : info4.data_file = r->data_file;
10240 0 : info4.config_file = r->config_file;
10241 0 : info4.help_file = r->help_file;
10242 0 : info4.monitor_name = r->monitor_name;
10243 0 : info4.default_datatype = r->default_datatype;
10244 0 : info4._ndr_size_dependent_files = r->_ndr_size_dependent_files;
10245 0 : info4.dependent_files = r->dependent_files;
10246 0 : info4._ndr_size_previous_names = r->_ndr_size_previous_names;
10247 0 : info4.previous_names = r->previous_names;
10248 :
10249 0 : info_ctr.level = 4;
10250 0 : info_ctr.info.info4 = &info4;
10251 :
10252 0 : if (ex) {
10253 0 : torture_assert(tctx,
10254 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10255 : "failed to test AddPrinterDriverEx level 4");
10256 : } else {
10257 0 : torture_assert(tctx,
10258 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_OK),
10259 : "failed to test AddPrinterDriver level 4");
10260 : }
10261 :
10262 0 : torture_assert(tctx,
10263 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 4, r->driver_name, &info),
10264 : "failed to find added printer driver");
10265 :
10266 0 : if (remote_driver_dir) {
10267 : int i;
10268 0 : ASSERT_DRIVER_PATH(tctx, info.info4.driver_path, remote_driver_dir, "unexpected path");
10269 0 : ASSERT_DRIVER_PATH(tctx, info.info4.data_file, remote_driver_dir, "unexpected path");
10270 0 : ASSERT_DRIVER_PATH(tctx, info.info4.config_file, remote_driver_dir, "unexpected path");
10271 0 : ASSERT_DRIVER_PATH(tctx, info.info4.help_file, remote_driver_dir, "unexpected path");
10272 0 : for (i=0; info.info4.dependent_files && info.info4.dependent_files[i] != NULL; i++) {
10273 0 : ASSERT_DRIVER_PATH(tctx, info.info4.dependent_files[i], remote_driver_dir, "unexpected path");
10274 : }
10275 : }
10276 :
10277 0 : return true;
10278 : }
10279 :
10280 0 : static bool test_AddPrinterDriver_args_level_6(struct torture_context *tctx,
10281 : struct dcerpc_binding_handle *b,
10282 : const char *server_name,
10283 : struct spoolss_AddDriverInfo8 *r,
10284 : uint32_t flags,
10285 : bool ex,
10286 : const char *remote_driver_dir)
10287 : {
10288 : struct spoolss_AddDriverInfoCtr info_ctr;
10289 : struct spoolss_AddDriverInfo6 info6;
10290 : union spoolss_DriverInfo info;
10291 :
10292 0 : info6.version = r->version;
10293 0 : info6.driver_name = r->driver_name;
10294 0 : info6.architecture = r->architecture;
10295 0 : info6.driver_path = r->driver_path;
10296 0 : info6.data_file = r->data_file;
10297 0 : info6.config_file = r->config_file;
10298 0 : info6.help_file = r->help_file;
10299 0 : info6.monitor_name = r->monitor_name;
10300 0 : info6.default_datatype = r->default_datatype;
10301 0 : info6._ndr_size_dependent_files = r->_ndr_size_dependent_files;
10302 0 : info6.dependent_files = r->dependent_files;
10303 0 : info6._ndr_size_previous_names = r->_ndr_size_previous_names;
10304 0 : info6.previous_names = r->previous_names;
10305 0 : info6.driver_date = r->driver_date;
10306 0 : info6.driver_version = r->driver_version;
10307 0 : info6.manufacturer_name = r->manufacturer_name;
10308 0 : info6.manufacturer_url = r->manufacturer_url;
10309 0 : info6.hardware_id = r->hardware_id;
10310 0 : info6.provider = r->provider;
10311 :
10312 0 : info_ctr.level = 6;
10313 0 : info_ctr.info.info6 = &info6;
10314 :
10315 0 : if (ex) {
10316 0 : torture_assert(tctx,
10317 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10318 : "failed to test AddPrinterDriverEx level 6");
10319 : } else {
10320 0 : torture_assert(tctx,
10321 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10322 : "failed to test AddPrinterDriver level 6");
10323 : }
10324 :
10325 : /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
10326 :
10327 0 : if (!ex) {
10328 0 : return true;
10329 : }
10330 :
10331 0 : torture_assert(tctx,
10332 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 6, r->driver_name, &info),
10333 : "failed to find added printer driver");
10334 :
10335 0 : if (remote_driver_dir) {
10336 : int i;
10337 0 : ASSERT_DRIVER_PATH(tctx, info.info6.driver_path, remote_driver_dir, "unexpected path");
10338 0 : ASSERT_DRIVER_PATH(tctx, info.info6.data_file, remote_driver_dir, "unexpected path");
10339 0 : ASSERT_DRIVER_PATH(tctx, info.info6.config_file, remote_driver_dir, "unexpected path");
10340 0 : ASSERT_DRIVER_PATH(tctx, info.info6.help_file, remote_driver_dir, "unexpected path");
10341 0 : for (i=0; info.info6.dependent_files && info.info6.dependent_files[i] != NULL; i++) {
10342 0 : ASSERT_DRIVER_PATH(tctx, info.info6.dependent_files[i], remote_driver_dir, "unexpected path");
10343 : }
10344 : }
10345 :
10346 0 : torture_assert_nttime_equal(tctx, info.info6.driver_date, info6.driver_date, "driverdate mismatch");
10347 0 : torture_assert_u64_equal(tctx, info.info6.driver_version, info6.driver_version, "driverversion mismatch");
10348 :
10349 0 : return true;
10350 : }
10351 :
10352 0 : static bool test_AddPrinterDriver_args_level_8(struct torture_context *tctx,
10353 : struct dcerpc_binding_handle *b,
10354 : const char *server_name,
10355 : struct spoolss_AddDriverInfo8 *r,
10356 : uint32_t flags,
10357 : bool ex,
10358 : const char *remote_driver_dir)
10359 : {
10360 : struct spoolss_AddDriverInfoCtr info_ctr;
10361 : union spoolss_DriverInfo info;
10362 :
10363 0 : info_ctr.level = 8;
10364 0 : info_ctr.info.info8 = r;
10365 :
10366 0 : if (ex) {
10367 0 : torture_assert(tctx,
10368 : test_AddPrinterDriverEx_exp(tctx, b, server_name, &info_ctr, flags, WERR_OK),
10369 : "failed to test AddPrinterDriverEx level 8");
10370 : } else {
10371 0 : torture_assert(tctx,
10372 : test_AddPrinterDriver_exp(tctx, b, server_name, &info_ctr, WERR_INVALID_LEVEL),
10373 : "failed to test AddPrinterDriver level 8");
10374 : }
10375 :
10376 : /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
10377 :
10378 0 : if (!ex) {
10379 0 : return true;
10380 : }
10381 :
10382 0 : torture_assert(tctx,
10383 : test_EnumPrinterDrivers_findone(tctx, b, server_name, r->architecture, 8, r->driver_name, &info),
10384 : "failed to find added printer driver");
10385 :
10386 0 : if (remote_driver_dir) {
10387 : int i;
10388 0 : ASSERT_DRIVER_PATH(tctx, info.info8.driver_path, remote_driver_dir, "unexpected path");
10389 0 : ASSERT_DRIVER_PATH(tctx, info.info8.data_file, remote_driver_dir, "unexpected path");
10390 0 : ASSERT_DRIVER_PATH(tctx, info.info8.config_file, remote_driver_dir, "unexpected path");
10391 0 : ASSERT_DRIVER_PATH(tctx, info.info8.help_file, remote_driver_dir, "unexpected path");
10392 0 : for (i=0; info.info8.dependent_files && info.info8.dependent_files[i] != NULL; i++) {
10393 0 : ASSERT_DRIVER_PATH(tctx, info.info8.dependent_files[i], remote_driver_dir, "unexpected path");
10394 : }
10395 : }
10396 :
10397 0 : torture_assert_nttime_equal(tctx, info.info8.driver_date, r->driver_date, "driverdate mismatch");
10398 0 : torture_assert_u64_equal(tctx, info.info8.driver_version, r->driver_version, "driverversion mismatch");
10399 :
10400 0 : return true;
10401 : }
10402 :
10403 : #undef ASSERT_DRIVER_PATH
10404 :
10405 0 : static bool test_DeletePrinterDriver_exp(struct torture_context *tctx,
10406 : struct dcerpc_binding_handle *b,
10407 : const char *server,
10408 : const char *driver,
10409 : const char *environment,
10410 : WERROR expected_result)
10411 : {
10412 : struct spoolss_DeletePrinterDriver r;
10413 :
10414 0 : r.in.server = server;
10415 0 : r.in.architecture = environment;
10416 0 : r.in.driver = driver;
10417 :
10418 0 : torture_comment(tctx, "Testing DeletePrinterDriver(%s)\n", driver);
10419 :
10420 0 : torture_assert_ntstatus_ok(tctx,
10421 : dcerpc_spoolss_DeletePrinterDriver_r(b, tctx, &r),
10422 : "DeletePrinterDriver failed");
10423 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
10424 : "DeletePrinterDriver failed with unexpected result");
10425 :
10426 0 : return true;
10427 : }
10428 :
10429 0 : static bool test_DeletePrinterDriverEx_exp(struct torture_context *tctx,
10430 : struct dcerpc_binding_handle *b,
10431 : const char *server,
10432 : const char *driver,
10433 : const char *environment,
10434 : uint32_t delete_flags,
10435 : uint32_t version,
10436 : WERROR expected_result)
10437 : {
10438 : struct spoolss_DeletePrinterDriverEx r;
10439 :
10440 0 : r.in.server = server;
10441 0 : r.in.architecture = environment;
10442 0 : r.in.driver = driver;
10443 0 : r.in.delete_flags = delete_flags;
10444 0 : r.in.version = version;
10445 :
10446 0 : torture_comment(tctx, "Testing DeletePrinterDriverEx(%s)\n", driver);
10447 :
10448 0 : torture_assert_ntstatus_ok(tctx,
10449 : dcerpc_spoolss_DeletePrinterDriverEx_r(b, tctx, &r),
10450 : "DeletePrinterDriverEx failed");
10451 0 : torture_assert_werr_equal(tctx, r.out.result, expected_result,
10452 : "DeletePrinterDriverEx failed with unexpected result");
10453 :
10454 0 : return true;
10455 : }
10456 :
10457 0 : static bool test_DeletePrinterDriver(struct torture_context *tctx,
10458 : struct dcerpc_binding_handle *b,
10459 : const char *server_name,
10460 : const char *driver,
10461 : const char *environment)
10462 : {
10463 0 : torture_assert(tctx,
10464 : test_DeletePrinterDriver_exp(tctx, b, server_name, driver, "FOOBAR", WERR_INVALID_ENVIRONMENT),
10465 : "failed to delete driver");
10466 :
10467 0 : torture_assert(tctx,
10468 : test_DeletePrinterDriver_exp(tctx, b, server_name, driver, environment, WERR_OK),
10469 : "failed to delete driver");
10470 :
10471 0 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name, environment, 1, driver, NULL)) {
10472 0 : torture_fail(tctx, "deleted driver still enumerated");
10473 : }
10474 :
10475 0 : torture_assert(tctx,
10476 : test_DeletePrinterDriver_exp(tctx, b, server_name, driver, environment, WERR_UNKNOWN_PRINTER_DRIVER),
10477 : "2nd delete failed");
10478 :
10479 0 : return true;
10480 : }
10481 :
10482 0 : static bool test_DeletePrinterDriverEx(struct torture_context *tctx,
10483 : struct dcerpc_binding_handle *b,
10484 : const char *server_name,
10485 : const char *driver,
10486 : const char *environment,
10487 : uint32_t delete_flags,
10488 : uint32_t version)
10489 : {
10490 0 : torture_assert(tctx,
10491 : test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, "FOOBAR", delete_flags, version, WERR_INVALID_ENVIRONMENT),
10492 : "failed to delete driver");
10493 :
10494 0 : torture_assert(tctx,
10495 : test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, environment, delete_flags, version, WERR_OK),
10496 : "failed to delete driver");
10497 :
10498 0 : if (test_EnumPrinterDrivers_findone(tctx, b, server_name, environment, 1, driver, NULL)) {
10499 0 : torture_fail(tctx, "deleted driver still enumerated");
10500 : }
10501 :
10502 0 : torture_assert(tctx,
10503 : test_DeletePrinterDriverEx_exp(tctx, b, server_name, driver, environment, delete_flags, version, WERR_UNKNOWN_PRINTER_DRIVER),
10504 : "2nd delete failed");
10505 :
10506 0 : return true;
10507 : }
10508 :
10509 0 : static bool test_PrinterDriver_args(struct torture_context *tctx,
10510 : struct dcerpc_binding_handle *b,
10511 : const char *server_name,
10512 : uint32_t level,
10513 : struct spoolss_AddDriverInfo8 *r,
10514 : uint32_t add_flags,
10515 : uint32_t delete_flags,
10516 : uint32_t delete_version,
10517 : bool ex,
10518 : const char *remote_driver_dir)
10519 : {
10520 0 : bool ret = true;
10521 :
10522 0 : switch (level) {
10523 0 : case 1:
10524 0 : ret = test_AddPrinterDriver_args_level_1(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10525 0 : break;
10526 0 : case 2:
10527 0 : ret = test_AddPrinterDriver_args_level_2(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10528 0 : break;
10529 0 : case 3:
10530 0 : ret = test_AddPrinterDriver_args_level_3(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10531 0 : break;
10532 0 : case 4:
10533 0 : ret = test_AddPrinterDriver_args_level_4(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10534 0 : break;
10535 0 : case 6:
10536 0 : ret = test_AddPrinterDriver_args_level_6(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10537 0 : break;
10538 0 : case 8:
10539 0 : ret = test_AddPrinterDriver_args_level_8(tctx, b, server_name, r, add_flags, ex, remote_driver_dir);
10540 0 : break;
10541 0 : default:
10542 0 : return false;
10543 : }
10544 :
10545 0 : if (ret == false) {
10546 0 : return ret;
10547 : }
10548 :
10549 0 : if (level == 1) {
10550 0 : return ret;
10551 : }
10552 :
10553 : /* spoolss_AddPrinterDriver does not deal with level 6 or 8 - gd */
10554 :
10555 0 : if (!ex && (level == 6 || level == 8)) {
10556 0 : return ret;
10557 : }
10558 :
10559 : {
10560 : struct dcerpc_pipe *p2;
10561 : struct policy_handle hive_handle;
10562 : struct dcerpc_binding_handle *b2;
10563 :
10564 0 : torture_assert_ntstatus_ok(tctx,
10565 : torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
10566 : "could not open winreg pipe");
10567 0 : b2 = p2->binding_handle;
10568 :
10569 0 : torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
10570 :
10571 0 : ret = test_GetDriverInfo_winreg(tctx, b, NULL, NULL, r->driver_name, r->architecture, r->version, b2, &hive_handle, server_name);
10572 :
10573 0 : test_winreg_CloseKey(tctx, b2, &hive_handle);
10574 :
10575 0 : talloc_free(p2);
10576 : }
10577 :
10578 0 : if (ex) {
10579 0 : return test_DeletePrinterDriverEx(tctx, b, server_name, r->driver_name, r->architecture, delete_flags, r->version);
10580 : } else {
10581 0 : return test_DeletePrinterDriver(tctx, b, server_name, r->driver_name, r->architecture);
10582 : }
10583 : }
10584 :
10585 0 : static bool fillup_printserver_info(struct torture_context *tctx,
10586 : struct dcerpc_pipe *p,
10587 : struct torture_driver_context *d)
10588 : {
10589 : struct policy_handle server_handle;
10590 0 : struct dcerpc_binding_handle *b = p->binding_handle;
10591 0 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
10592 :
10593 0 : torture_assert(tctx,
10594 : test_OpenPrinter_server(tctx, p, &server_handle),
10595 : "failed to open printserver");
10596 0 : torture_assert(tctx,
10597 : test_get_environment(tctx, b, &server_handle, &d->remote.environment),
10598 : "failed to get environment");
10599 0 : torture_assert(tctx,
10600 : test_ClosePrinter(tctx, b, &server_handle),
10601 : "failed to close printserver");
10602 :
10603 0 : torture_assert(tctx,
10604 : test_GetPrinterDriverDirectory_getdir(tctx, b, server_name_slash,
10605 : d->local.environment ? d->local.environment : d->remote.environment,
10606 : &d->remote.driver_directory),
10607 : "failed to get driver directory");
10608 :
10609 0 : return true;
10610 : }
10611 :
10612 0 : static const char *driver_directory_dir(const char *driver_directory)
10613 : {
10614 : char *p;
10615 :
10616 0 : p = strrchr(driver_directory, '\\');
10617 0 : if (p) {
10618 0 : return p+1;
10619 : }
10620 :
10621 0 : return NULL;
10622 : }
10623 :
10624 0 : static const char *driver_directory_share(struct torture_context *tctx,
10625 : const char *driver_directory)
10626 : {
10627 : const char *p;
10628 : char *tok;
10629 :
10630 0 : if (driver_directory[0] == '\\' && driver_directory[1] == '\\') {
10631 0 : driver_directory += 2;
10632 : }
10633 :
10634 0 : p = talloc_strdup(tctx, driver_directory);
10635 :
10636 0 : torture_assert(tctx,
10637 : next_token_talloc(tctx, &p, &tok, "\\"),
10638 : "cannot explode uri");
10639 0 : torture_assert(tctx,
10640 : next_token_talloc(tctx, &p, &tok, "\\"),
10641 : "cannot explode uri");
10642 :
10643 0 : return tok;
10644 : }
10645 :
10646 : #define CREATE_PRINTER_DRIVER_PATH(_d, _file) \
10647 : talloc_asprintf((_d), "%s\\%s\\%s", (_d)->remote.driver_directory, (_d)->remote.driver_upload_directory, (_file))
10648 :
10649 :
10650 0 : static bool create_printer_driver_directory(struct torture_context *tctx,
10651 : struct smbcli_state *cli,
10652 : struct torture_driver_context *d)
10653 : {
10654 : char *driver_dir;
10655 :
10656 0 : if (d->remote.driver_upload_directory == NULL) {
10657 0 : return true;
10658 : }
10659 :
10660 0 : driver_dir = talloc_asprintf(tctx,
10661 : "%s\\%s",
10662 : driver_directory_dir(d->remote.driver_directory),
10663 : d->remote.driver_upload_directory);
10664 0 : torture_assert_not_null(tctx, driver_dir, "ENOMEM");
10665 :
10666 0 : torture_comment(tctx,
10667 : "Create remote driver directory: %s\n",
10668 : driver_dir);
10669 :
10670 0 : torture_assert_ntstatus_ok(tctx,
10671 : smbcli_mkdir(cli->tree,
10672 : driver_dir),
10673 : "Failed to create driver directory");
10674 :
10675 0 : return true;
10676 : }
10677 :
10678 0 : static bool upload_printer_driver_file(struct torture_context *tctx,
10679 : struct smbcli_state *cli,
10680 : struct torture_driver_context *d,
10681 : const char *file_name)
10682 : {
10683 : FILE *f;
10684 : int fnum;
10685 : uint8_t *buf;
10686 0 : int maxwrite = 64512;
10687 0 : off_t nread = 0;
10688 0 : size_t start = 0;
10689 0 : const char *remote_dir = driver_directory_dir(d->remote.driver_directory);
10690 : const char *remote_name;
10691 : const char *local_name;
10692 : const char *p;
10693 :
10694 0 : if (!file_name || strlen(file_name) == 0) {
10695 0 : return true;
10696 : }
10697 :
10698 0 : p = strrchr(file_name, '\\');
10699 0 : if (p == NULL) {
10700 0 : p = file_name;
10701 : } else {
10702 0 : p++;
10703 : }
10704 :
10705 0 : local_name = talloc_asprintf(tctx, "%s/%s", d->local.driver_directory, p);
10706 0 : torture_assert_not_null(tctx, local_name, "ENOMEM");
10707 0 : if (d->remote.driver_upload_directory != NULL) {
10708 0 : remote_name = talloc_asprintf(tctx,
10709 : "%s\\%s\\%s",
10710 : remote_dir,
10711 : d->remote.driver_upload_directory,
10712 : p);
10713 : } else {
10714 0 : remote_name = talloc_asprintf(tctx, "%s\\%s", remote_dir, p);
10715 : }
10716 0 : torture_assert_not_null(tctx, remote_name, "ENOMEM");
10717 :
10718 0 : torture_comment(tctx, "Uploading %s to %s\n", local_name, remote_name);
10719 :
10720 0 : fnum = smbcli_open(cli->tree, remote_name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
10721 0 : if (fnum == -1) {
10722 0 : torture_fail(tctx, talloc_asprintf(tctx, "failed to open remote file: %s\n", remote_name));
10723 : }
10724 :
10725 0 : f = fopen(local_name, "r");
10726 0 : if (f == NULL) {
10727 0 : torture_fail(tctx, talloc_asprintf(tctx, "failed to open local file: %s\n", local_name));
10728 : }
10729 :
10730 0 : buf = talloc_array(tctx, uint8_t, maxwrite);
10731 0 : if (!buf) {
10732 0 : fclose(f);
10733 0 : return false;
10734 : }
10735 :
10736 0 : while (!feof(f)) {
10737 0 : int n = maxwrite;
10738 : int ret;
10739 :
10740 0 : if ((n = fread(buf, 1, n, f)) < 1) {
10741 0 : if((n == 0) && feof(f))
10742 0 : break; /* Empty local file. */
10743 :
10744 0 : torture_warning(tctx,
10745 0 : "failed to read file: %s\n", strerror(errno));
10746 0 : break;
10747 : }
10748 :
10749 0 : ret = smbcli_write(cli->tree, fnum, 0, buf, nread + start, n);
10750 :
10751 0 : if (n != ret) {
10752 0 : torture_warning(tctx,
10753 : "failed to write file: %s\n", smbcli_errstr(cli->tree));
10754 0 : break;
10755 : }
10756 :
10757 0 : nread += n;
10758 : }
10759 :
10760 0 : fclose(f);
10761 :
10762 0 : torture_assert_ntstatus_ok(tctx,
10763 : smbcli_close(cli->tree, fnum),
10764 : "failed to close file");
10765 :
10766 0 : return true;
10767 : }
10768 :
10769 0 : static bool connect_printer_driver_share(struct torture_context *tctx,
10770 : const char *server_name,
10771 : const char *share_name,
10772 : struct smbcli_state **cli)
10773 : {
10774 : struct smbcli_options smb_options;
10775 : struct smbcli_session_options smb_session_options;
10776 :
10777 0 : torture_comment(tctx, "Connecting printer driver share '%s' on '%s'\n",
10778 : share_name, server_name);
10779 :
10780 0 : lpcfg_smbcli_options(tctx->lp_ctx, &smb_options);
10781 0 : lpcfg_smbcli_session_options(tctx->lp_ctx, &smb_session_options);
10782 :
10783 0 : torture_assert_ntstatus_ok(tctx,
10784 : smbcli_full_connection(tctx, cli, server_name,
10785 : lpcfg_smb_ports(tctx->lp_ctx),
10786 : share_name, NULL,
10787 : lpcfg_socket_options(tctx->lp_ctx),
10788 : samba_cmdline_get_creds(),
10789 : lpcfg_resolve_context(tctx->lp_ctx),
10790 : tctx->ev,
10791 : &smb_options,
10792 : &smb_session_options,
10793 : lpcfg_gensec_settings(tctx, tctx->lp_ctx)),
10794 : "failed to open driver share");
10795 :
10796 0 : return true;
10797 : }
10798 :
10799 0 : static bool upload_printer_driver(struct torture_context *tctx,
10800 : const char *server_name,
10801 : struct torture_driver_context *d)
10802 : {
10803 : struct smbcli_state *cli;
10804 0 : const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
10805 : int i;
10806 :
10807 0 : torture_assert(tctx,
10808 : connect_printer_driver_share(tctx, server_name, share_name, &cli),
10809 : "failed to connect to driver share");
10810 :
10811 0 : torture_comment(tctx, "Uploading printer driver files to \\\\%s\\%s\n",
10812 : server_name, share_name);
10813 :
10814 0 : torture_assert(tctx,
10815 : create_printer_driver_directory(tctx, cli, d),
10816 : "failed to create driver directory");
10817 :
10818 0 : torture_assert(tctx,
10819 : upload_printer_driver_file(tctx, cli, d, d->info8.driver_path),
10820 : "failed to upload driver_path");
10821 0 : torture_assert(tctx,
10822 : upload_printer_driver_file(tctx, cli, d, d->info8.data_file),
10823 : "failed to upload data_file");
10824 0 : torture_assert(tctx,
10825 : upload_printer_driver_file(tctx, cli, d, d->info8.config_file),
10826 : "failed to upload config_file");
10827 0 : torture_assert(tctx,
10828 : upload_printer_driver_file(tctx, cli, d, d->info8.help_file),
10829 : "failed to upload help_file");
10830 0 : if (d->info8.dependent_files) {
10831 0 : for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
10832 0 : torture_assert(tctx,
10833 : upload_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]),
10834 : "failed to upload dependent_files");
10835 : }
10836 : }
10837 :
10838 0 : talloc_free(cli);
10839 :
10840 0 : return true;
10841 : }
10842 :
10843 0 : static bool check_printer_driver_file(struct torture_context *tctx,
10844 : struct smbcli_state *cli,
10845 : struct torture_driver_context *d,
10846 : const char *file_name)
10847 : {
10848 0 : const char *remote_arch_dir = driver_directory_dir(d->remote.driver_directory);
10849 0 : const char *remote_name = talloc_asprintf(tctx, "%s\\%d\\%s",
10850 : remote_arch_dir,
10851 0 : d->info8.version,
10852 : file_name);
10853 : int fnum;
10854 :
10855 0 : torture_assert(tctx, (file_name && strlen(file_name) != 0), "invalid filename");
10856 :
10857 0 : torture_comment(tctx, "checking for driver file at %s\n", remote_name);
10858 :
10859 0 : fnum = smbcli_open(cli->tree, remote_name, O_RDONLY, DENY_NONE);
10860 0 : if (fnum == -1) {
10861 0 : return false;
10862 : }
10863 :
10864 0 : torture_assert_ntstatus_ok(tctx,
10865 : smbcli_close(cli->tree, fnum),
10866 : "failed to close driver file");
10867 :
10868 0 : return true;
10869 : }
10870 :
10871 0 : static bool check_printer_driver_files(struct torture_context *tctx,
10872 : const char *server_name,
10873 : struct torture_driver_context *d,
10874 : bool expect_exist)
10875 : {
10876 : struct smbcli_state *cli;
10877 0 : const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
10878 : int i;
10879 :
10880 0 : torture_assert(tctx,
10881 : connect_printer_driver_share(tctx, server_name, share_name, &cli),
10882 : "failed to connect to driver share");
10883 :
10884 0 : torture_comment(tctx, "checking %sexistent driver files at \\\\%s\\%s\n",
10885 : (expect_exist ? "": "non-"),
10886 : server_name, share_name);
10887 :
10888 0 : if (d->info8.driver_path && d->info8.driver_path[0]) {
10889 0 : torture_assert(tctx,
10890 : check_printer_driver_file(tctx, cli, d, d->info8.driver_path) == expect_exist,
10891 : "failed driver_path check");
10892 : }
10893 0 : if (d->info8.data_file && d->info8.data_file[0]) {
10894 0 : torture_assert(tctx,
10895 : check_printer_driver_file(tctx, cli, d, d->info8.data_file) == expect_exist,
10896 : "failed data_file check");
10897 : }
10898 0 : if (d->info8.config_file && d->info8.config_file[0]) {
10899 0 : torture_assert(tctx,
10900 : check_printer_driver_file(tctx, cli, d, d->info8.config_file) == expect_exist,
10901 : "failed config_file check");
10902 : }
10903 0 : if (d->info8.help_file && d->info8.help_file[0]) {
10904 0 : torture_assert(tctx,
10905 : check_printer_driver_file(tctx, cli, d, d->info8.help_file) == expect_exist,
10906 : "failed help_file check");
10907 : }
10908 0 : if (d->info8.dependent_files) {
10909 0 : for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
10910 0 : torture_assert(tctx,
10911 : check_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]) == expect_exist,
10912 : "failed dependent_files check");
10913 : }
10914 : }
10915 :
10916 0 : talloc_free(cli);
10917 :
10918 0 : return true;
10919 : }
10920 :
10921 0 : static bool remove_printer_driver_file(struct torture_context *tctx,
10922 : struct smbcli_state *cli,
10923 : struct torture_driver_context *d,
10924 : const char *file_name)
10925 : {
10926 : const char *remote_name;
10927 0 : const char *remote_dir = driver_directory_dir(d->remote.driver_directory);
10928 :
10929 0 : if (!file_name || strlen(file_name) == 0) {
10930 0 : return true;
10931 : }
10932 :
10933 0 : remote_name = talloc_asprintf(tctx, "%s\\%s", remote_dir, file_name);
10934 :
10935 0 : torture_comment(tctx, "Removing %s\n", remote_name);
10936 :
10937 0 : torture_assert_ntstatus_ok(tctx,
10938 : smbcli_unlink(cli->tree, remote_name),
10939 : "failed to unlink");
10940 :
10941 0 : return true;
10942 : }
10943 :
10944 0 : static bool remove_printer_driver(struct torture_context *tctx,
10945 : const char *server_name,
10946 : struct torture_driver_context *d)
10947 : {
10948 : struct smbcli_state *cli;
10949 0 : const char *share_name = driver_directory_share(tctx, d->remote.driver_directory);
10950 : int i;
10951 :
10952 0 : torture_assert(tctx,
10953 : connect_printer_driver_share(tctx, server_name, share_name, &cli),
10954 : "failed to connect to driver share");
10955 :
10956 0 : torture_comment(tctx, "Removing printer driver files from \\\\%s\\%s\n",
10957 : server_name, share_name);
10958 :
10959 0 : torture_assert(tctx,
10960 : remove_printer_driver_file(tctx, cli, d, d->info8.driver_path),
10961 : "failed to remove driver_path");
10962 0 : torture_assert(tctx,
10963 : remove_printer_driver_file(tctx, cli, d, d->info8.data_file),
10964 : "failed to remove data_file");
10965 0 : if (!strequal(d->info8.config_file, d->info8.driver_path)) {
10966 0 : torture_assert(tctx,
10967 : remove_printer_driver_file(tctx, cli, d, d->info8.config_file),
10968 : "failed to remove config_file");
10969 : }
10970 0 : torture_assert(tctx,
10971 : remove_printer_driver_file(tctx, cli, d, d->info8.help_file),
10972 : "failed to remove help_file");
10973 0 : if (d->info8.dependent_files) {
10974 0 : for (i=0; d->info8.dependent_files->string && d->info8.dependent_files->string[i] != NULL; i++) {
10975 0 : if (strequal(d->info8.dependent_files->string[i], d->info8.driver_path) ||
10976 0 : strequal(d->info8.dependent_files->string[i], d->info8.data_file) ||
10977 0 : strequal(d->info8.dependent_files->string[i], d->info8.config_file) ||
10978 0 : strequal(d->info8.dependent_files->string[i], d->info8.help_file)) {
10979 0 : continue;
10980 : }
10981 0 : torture_assert(tctx,
10982 : remove_printer_driver_file(tctx, cli, d, d->info8.dependent_files->string[i]),
10983 : "failed to remove dependent_files");
10984 : }
10985 : }
10986 :
10987 0 : talloc_free(cli);
10988 :
10989 0 : return true;
10990 :
10991 : }
10992 :
10993 0 : static bool test_add_driver_arg(struct torture_context *tctx,
10994 : struct dcerpc_pipe *p,
10995 : struct torture_driver_context *d)
10996 : {
10997 0 : bool ret = true;
10998 0 : struct dcerpc_binding_handle *b = p->binding_handle;
10999 0 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11000 0 : uint32_t levels[] = { 1, 2, 3, 4, 6, 8 };
11001 : int i;
11002 : struct spoolss_AddDriverInfo8 info8;
11003 0 : uint32_t add_flags = APD_COPY_NEW_FILES;
11004 0 : uint32_t delete_flags = 0;
11005 :
11006 0 : ZERO_STRUCT(info8);
11007 :
11008 0 : torture_comment(tctx, "Testing PrinterDriver%s '%s' for environment '%s'\n",
11009 0 : d->ex ? "Ex" : "", d->info8.driver_name, d->local.environment);
11010 :
11011 0 : torture_assert(tctx,
11012 : fillup_printserver_info(tctx, p, d),
11013 : "failed to fillup printserver info");
11014 :
11015 0 : if (!directory_exist(d->local.driver_directory)) {
11016 0 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11017 : }
11018 :
11019 0 : torture_assert(tctx,
11020 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11021 : "failed to upload printer driver");
11022 :
11023 0 : info8 = d->info8;
11024 0 : if (d->info8.dependent_files) {
11025 0 : info8.dependent_files = talloc_zero(tctx, struct spoolss_StringArray);
11026 0 : if (d->info8.dependent_files->string) {
11027 0 : for (i=0; d->info8.dependent_files->string[i] != NULL; i++) {
11028 : }
11029 0 : info8.dependent_files->string = talloc_zero_array(info8.dependent_files, const char *, i+1);
11030 0 : for (i=0; d->info8.dependent_files->string[i] != NULL; i++) {
11031 0 : info8.dependent_files->string[i] = talloc_strdup(info8.dependent_files->string, d->info8.dependent_files->string[i]);
11032 : }
11033 : }
11034 : }
11035 :
11036 0 : for (i=0; i < ARRAY_SIZE(levels); i++) {
11037 :
11038 0 : if (torture_setting_bool(tctx, "samba3", false)) {
11039 0 : switch (levels[i]) {
11040 0 : case 2:
11041 : case 4:
11042 0 : torture_comment(tctx, "skipping level %d against samba\n", levels[i]);
11043 0 : continue;
11044 0 : default:
11045 0 : break;
11046 : }
11047 0 : }
11048 0 : if (torture_setting_bool(tctx, "w2k3", false)) {
11049 0 : switch (levels[i]) {
11050 0 : case 8:
11051 0 : torture_comment(tctx, "skipping level %d against w2k3\n", levels[i]);
11052 0 : continue;
11053 0 : default:
11054 0 : break;
11055 : }
11056 0 : }
11057 :
11058 0 : torture_comment(tctx,
11059 : "Testing PrinterDriver%s '%s' add & delete level %d\n",
11060 0 : d->ex ? "Ex" : "", info8.driver_name, levels[i]);
11061 :
11062 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);
11063 : }
11064 :
11065 0 : info8.driver_path = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.driver_path);
11066 0 : info8.data_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.data_file);
11067 0 : if (d->info8.config_file) {
11068 0 : info8.config_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.config_file);
11069 : }
11070 0 : if (d->info8.help_file) {
11071 0 : info8.help_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.help_file);
11072 : }
11073 0 : if (d->info8.dependent_files && d->info8.dependent_files->string) {
11074 0 : for (i=0; d->info8.dependent_files->string[i] != NULL; i++) {
11075 0 : info8.dependent_files->string[i] = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.dependent_files->string[i]);
11076 : }
11077 : }
11078 :
11079 0 : for (i=0; i < ARRAY_SIZE(levels); i++) {
11080 :
11081 0 : if (torture_setting_bool(tctx, "samba3", false)) {
11082 0 : switch (levels[i]) {
11083 0 : case 2:
11084 : case 4:
11085 0 : continue;
11086 0 : default:
11087 0 : break;
11088 : }
11089 0 : }
11090 0 : if (torture_setting_bool(tctx, "w2k3", false)) {
11091 0 : switch (levels[i]) {
11092 0 : case 8:
11093 0 : torture_comment(tctx, "skipping level %d against w2k3\n", levels[i]);
11094 0 : continue;
11095 0 : default:
11096 0 : break;
11097 : }
11098 0 : }
11099 :
11100 0 : torture_comment(tctx,
11101 : "Testing PrinterDriver%s '%s' add & delete level %d (full unc paths)\n",
11102 0 : d->ex ? "Ex" : "", info8.driver_name, levels[i]);
11103 :
11104 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);
11105 : }
11106 :
11107 0 : torture_assert(tctx,
11108 : remove_printer_driver(tctx, dcerpc_server_name(p), d),
11109 : "failed to remove printer driver");
11110 :
11111 0 : torture_comment(tctx, "\n");
11112 :
11113 0 : return ret;
11114 : }
11115 :
11116 0 : static bool test_add_driver_ex_64(struct torture_context *tctx,
11117 : struct dcerpc_pipe *p)
11118 : {
11119 : struct torture_driver_context *d;
11120 :
11121 0 : d = talloc_zero(tctx, struct torture_driver_context);
11122 :
11123 0 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_x64);
11124 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
11125 :
11126 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11127 0 : d->info8.driver_name = TORTURE_DRIVER_EX;
11128 0 : d->info8.architecture = d->local.environment;
11129 0 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11130 0 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11131 0 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11132 0 : d->ex = true;
11133 :
11134 0 : return test_add_driver_arg(tctx, p, d);
11135 : }
11136 :
11137 0 : static bool test_add_driver_ex_32(struct torture_context *tctx,
11138 : struct dcerpc_pipe *p)
11139 : {
11140 : struct torture_driver_context *d;
11141 :
11142 0 : d = talloc_zero(tctx, struct torture_driver_context);
11143 :
11144 0 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11145 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11146 :
11147 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11148 0 : d->info8.driver_name = TORTURE_DRIVER_EX;
11149 0 : d->info8.architecture = d->local.environment;
11150 0 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11151 0 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11152 0 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11153 0 : d->ex = true;
11154 :
11155 0 : return test_add_driver_arg(tctx, p, d);
11156 : }
11157 :
11158 0 : static bool test_add_driver_64(struct torture_context *tctx,
11159 : struct dcerpc_pipe *p)
11160 : {
11161 : struct torture_driver_context *d;
11162 :
11163 0 : d = talloc_zero(tctx, struct torture_driver_context);
11164 :
11165 0 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_x64);
11166 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
11167 :
11168 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11169 0 : d->info8.driver_name = TORTURE_DRIVER_ADD;
11170 0 : d->info8.architecture = d->local.environment;
11171 0 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11172 0 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11173 0 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11174 0 : d->ex = false;
11175 :
11176 0 : return test_add_driver_arg(tctx, p, d);
11177 : }
11178 :
11179 0 : static bool test_add_driver_32(struct torture_context *tctx,
11180 : struct dcerpc_pipe *p)
11181 : {
11182 : struct torture_driver_context *d;
11183 :
11184 0 : d = talloc_zero(tctx, struct torture_driver_context);
11185 :
11186 0 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11187 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11188 :
11189 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11190 0 : d->info8.driver_name = TORTURE_DRIVER_ADD;
11191 0 : d->info8.architecture = d->local.environment;
11192 0 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11193 0 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11194 0 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11195 0 : d->ex = false;
11196 :
11197 0 : return test_add_driver_arg(tctx, p, d);
11198 : }
11199 :
11200 0 : static bool test_add_driver_adobe(struct torture_context *tctx,
11201 : struct dcerpc_pipe *p)
11202 : {
11203 : struct torture_driver_context *d;
11204 :
11205 0 : if (!torture_setting_bool(tctx, "samba3", false)) {
11206 0 : torture_skip(tctx, "skipping adobe test which only works against samba3");
11207 : }
11208 :
11209 0 : d = talloc_zero(tctx, struct torture_driver_context);
11210 :
11211 0 : d->local.environment = talloc_strdup(d, "Windows 4.0");
11212 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
11213 :
11214 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
11215 0 : d->info8.driver_name = TORTURE_DRIVER_ADOBE;
11216 0 : d->info8.architecture = d->local.environment;
11217 0 : d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
11218 0 : d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
11219 0 : d->info8.config_file = talloc_strdup(d, "ADOBEPS4.DRV");
11220 : #if 0
11221 : d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
11222 : d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
11223 : #endif
11224 0 : d->ex = false;
11225 :
11226 0 : return test_add_driver_arg(tctx, p, d);
11227 : }
11228 :
11229 0 : static bool test_add_driver_adobe_cupsaddsmb(struct torture_context *tctx,
11230 : struct dcerpc_pipe *p)
11231 : {
11232 : struct torture_driver_context *d;
11233 : struct spoolss_StringArray *a;
11234 :
11235 0 : if (!torture_setting_bool(tctx, "samba3", false)) {
11236 0 : torture_skip(tctx, "skipping cupsaddsmb test which only works against samba3");
11237 : }
11238 :
11239 0 : d = talloc_zero(tctx, struct torture_driver_context);
11240 :
11241 0 : d->local.environment = talloc_strdup(d, "Windows 4.0");
11242 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
11243 :
11244 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
11245 0 : d->info8.driver_name = TORTURE_DRIVER_ADOBE_CUPSADDSMB;
11246 0 : d->info8.architecture = d->local.environment;
11247 0 : d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
11248 0 : d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
11249 0 : d->info8.config_file = NULL;
11250 0 : d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
11251 0 : d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
11252 0 : d->info8.default_datatype = talloc_strdup(d, "RAW");
11253 :
11254 0 : a = talloc_zero(d, struct spoolss_StringArray);
11255 0 : a->string = talloc_zero_array(a, const char *, 7);
11256 0 : a->string[0] = talloc_strdup(a->string, "ADOBEPS4.DRV");
11257 0 : a->string[1] = talloc_strdup(a->string, "DEFPRTR2.PPD");
11258 0 : a->string[2] = talloc_strdup(a->string, "ADOBEPS4.HLP");
11259 0 : a->string[3] = talloc_strdup(a->string, "PSMON.DLL");
11260 0 : a->string[4] = talloc_strdup(a->string, "ADFONTS.MFM");
11261 0 : a->string[5] = talloc_strdup(a->string, "ICONLIB.DLL");
11262 :
11263 0 : d->info8.dependent_files = a;
11264 0 : d->ex = false;
11265 :
11266 0 : return test_add_driver_arg(tctx, p, d);
11267 : }
11268 :
11269 0 : static bool test_add_driver_timestamps(struct torture_context *tctx,
11270 : struct dcerpc_pipe *p)
11271 : {
11272 : struct torture_driver_context *d;
11273 0 : struct timeval t = timeval_current();
11274 :
11275 0 : d = talloc_zero(tctx, struct torture_driver_context);
11276 :
11277 0 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11278 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11279 :
11280 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11281 0 : d->info8.driver_name = TORTURE_DRIVER_TIMESTAMPS;
11282 0 : d->info8.architecture = d->local.environment;
11283 0 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11284 0 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11285 0 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11286 0 : d->info8.driver_date = timeval_to_nttime(&t);
11287 0 : d->ex = true;
11288 :
11289 0 : torture_assert(tctx,
11290 : test_add_driver_arg(tctx, p, d),
11291 : "");
11292 :
11293 0 : unix_to_nt_time(&d->info8.driver_date, 1);
11294 :
11295 0 : torture_assert(tctx,
11296 : test_add_driver_arg(tctx, p, d),
11297 : "");
11298 :
11299 0 : return true;
11300 : }
11301 :
11302 0 : static bool test_multiple_drivers(struct torture_context *tctx,
11303 : struct dcerpc_pipe *p)
11304 : {
11305 : struct torture_driver_context *d;
11306 0 : struct dcerpc_binding_handle *b = p->binding_handle;
11307 0 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11308 : int i;
11309 : struct spoolss_AddDriverInfo8 info8;
11310 0 : uint32_t add_flags = APD_COPY_NEW_FILES;
11311 0 : uint32_t delete_flags = 0;
11312 :
11313 0 : d = talloc_zero(tctx, struct torture_driver_context);
11314 :
11315 0 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_NT_X86);
11316 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
11317 :
11318 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11319 0 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11320 0 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11321 0 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11322 0 : d->info8.architecture = d->local.environment;
11323 0 : d->ex = true;
11324 :
11325 0 : torture_assert(tctx,
11326 : fillup_printserver_info(tctx, p, d),
11327 : "failed to fillup printserver info");
11328 :
11329 0 : if (!directory_exist(d->local.driver_directory)) {
11330 0 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11331 : }
11332 :
11333 0 : torture_assert(tctx,
11334 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11335 : "failed to upload printer driver");
11336 :
11337 0 : info8 = d->info8;
11338 :
11339 0 : for (i=0; i < 3; i++) {
11340 0 : info8.driver_name = talloc_asprintf(d, "torture_test_driver_%d", i);
11341 :
11342 0 : torture_assert(tctx,
11343 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &info8, add_flags, true, NULL),
11344 : "failed to add driver");
11345 : }
11346 :
11347 0 : torture_assert(tctx,
11348 : test_DeletePrinterDriverEx(tctx, b, server_name_slash, "torture_test_driver_0", info8.architecture, delete_flags, info8.version),
11349 : "failed to delete driver");
11350 :
11351 0 : torture_assert(tctx,
11352 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, info8.architecture, 3, "torture_test_driver_1", NULL),
11353 : "torture_test_driver_1 no longer on the server");
11354 :
11355 0 : torture_assert(tctx,
11356 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, info8.architecture, 3, "torture_test_driver_2", NULL),
11357 : "torture_test_driver_2 no longer on the server");
11358 :
11359 0 : torture_assert(tctx,
11360 : test_DeletePrinterDriverEx(tctx, b, server_name_slash, "torture_test_driver_1", info8.architecture, delete_flags, info8.version),
11361 : "failed to delete driver");
11362 :
11363 0 : torture_assert(tctx,
11364 : test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, info8.architecture, 3, "torture_test_driver_2", NULL),
11365 : "torture_test_driver_2 no longer on the server");
11366 :
11367 0 : torture_assert(tctx,
11368 : test_DeletePrinterDriverEx(tctx, b, server_name_slash, "torture_test_driver_2", info8.architecture, delete_flags, info8.version),
11369 : "failed to delete driver");
11370 :
11371 0 : torture_assert(tctx,
11372 : remove_printer_driver(tctx, dcerpc_server_name(p), d),
11373 : "failed to remove printer driver");
11374 :
11375 0 : return true;
11376 : }
11377 :
11378 0 : static bool test_driver_copy_from_directory(struct torture_context *tctx,
11379 : struct dcerpc_pipe *p,
11380 : const char *architecture)
11381 : {
11382 : struct torture_driver_context *d;
11383 : struct spoolss_StringArray *a;
11384 0 : uint32_t add_flags = APD_COPY_NEW_FILES|APD_COPY_FROM_DIRECTORY|APD_RETURN_BLOCKING_STATUS_CODE;
11385 0 : uint32_t delete_flags = DPD_DELETE_ALL_FILES;
11386 0 : struct dcerpc_binding_handle *b = p->binding_handle;
11387 0 : const char *server_name_slash = talloc_asprintf(tctx,
11388 : "\\\\%s",
11389 : dcerpc_server_name(p));
11390 0 : struct GUID guid = GUID_random();
11391 0 : bool ok = false;
11392 :
11393 0 : d = talloc_zero(tctx, struct torture_driver_context);
11394 0 : torture_assert_not_null(tctx, d, "ENOMEM");
11395 :
11396 0 : d->local.environment = talloc_strdup(d, architecture);
11397 0 : torture_assert_not_null_goto(tctx, d->local.environment, ok, done, "ENOMEM");
11398 :
11399 0 : if (strequal(architecture, SPOOLSS_ARCHITECTURE_x64)) {
11400 0 : d->local.driver_directory =
11401 0 : talloc_strdup(d, "/usr/share/cups/drivers/x64");
11402 : } else {
11403 0 : d->local.driver_directory =
11404 0 : talloc_strdup(d, "/usr/share/cups/drivers/i386");
11405 : }
11406 0 : torture_assert_not_null_goto(tctx, d->local.driver_directory, ok, done, "ENOMEM");
11407 :
11408 0 : d->remote.driver_upload_directory = GUID_string2(d, &guid);
11409 0 : torture_assert_not_null_goto(tctx, d->remote.driver_upload_directory, ok, done, "ENOMEM");
11410 :
11411 0 : torture_assert(tctx,
11412 : fillup_printserver_info(tctx, p, d),
11413 : "failed to fillup printserver info");
11414 :
11415 0 : d->ex = true;
11416 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11417 0 : d->info8.driver_name = TORTURE_DRIVER_COPY_DIR;
11418 0 : d->info8.architecture = d->local.environment;
11419 :
11420 0 : d->info8.driver_path = CREATE_PRINTER_DRIVER_PATH(d, "pscript5.dll");
11421 0 : torture_assert_not_null_goto(tctx, d->info8.driver_path, ok, done, "ENOMEM");
11422 0 : d->info8.data_file = CREATE_PRINTER_DRIVER_PATH(d, "cups6.ppd");
11423 0 : torture_assert_not_null_goto(tctx, d->info8.data_file, ok, done, "ENOMEM");
11424 0 : d->info8.config_file = CREATE_PRINTER_DRIVER_PATH(d, "cupsui6.dll");
11425 0 : torture_assert_not_null_goto(tctx, d->info8.config_file, ok, done, "ENOMEM");
11426 0 : d->info8.help_file = CREATE_PRINTER_DRIVER_PATH(d, "pscript.hlp");
11427 0 : torture_assert_not_null_goto(tctx, d->info8.help_file, ok, done, "ENOMEM");
11428 :
11429 0 : a = talloc_zero(d, struct spoolss_StringArray);
11430 0 : torture_assert_not_null_goto(tctx, a, ok, done, "ENOMEM");
11431 0 : a->string = talloc_zero_array(a, const char *, 3);
11432 0 : torture_assert_not_null_goto(tctx, a->string, ok, done, "ENOMEM");
11433 0 : a->string[0] = CREATE_PRINTER_DRIVER_PATH(d, "cups6.inf");
11434 0 : torture_assert_not_null_goto(tctx, a->string[0], ok, done, "ENOMEM");
11435 0 : a->string[1] = CREATE_PRINTER_DRIVER_PATH(d, "cups6.ini");
11436 0 : torture_assert_not_null_goto(tctx, a->string[1], ok, done, "ENOMEM");
11437 :
11438 0 : d->info8.dependent_files = a;
11439 :
11440 0 : if (!directory_exist(d->local.driver_directory)) {
11441 0 : torture_skip(tctx,
11442 : "Skipping Printer Driver test as no local drivers "
11443 : "are available");
11444 : }
11445 :
11446 0 : torture_assert(tctx,
11447 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11448 : "failed to upload printer driver");
11449 :
11450 0 : torture_assert(tctx,
11451 : test_AddPrinterDriver_args_level_3(tctx,
11452 : b,
11453 : server_name_slash,
11454 : &d->info8,
11455 : add_flags,
11456 : true,
11457 : NULL),
11458 : "failed to add driver");
11459 :
11460 0 : torture_assert(tctx,
11461 : test_DeletePrinterDriverEx(tctx,
11462 : b,
11463 : server_name_slash,
11464 : d->info8.driver_name,
11465 : d->local.environment,
11466 : delete_flags,
11467 : d->info8.version),
11468 : "failed to delete driver");
11469 :
11470 0 : torture_assert(tctx,
11471 : check_printer_driver_files(tctx,
11472 : dcerpc_server_name(p),
11473 : d,
11474 : false),
11475 : "printer driver file check failed");
11476 :
11477 0 : ok = true;
11478 0 : done:
11479 0 : talloc_free(d);
11480 0 : return ok;
11481 : }
11482 :
11483 0 : static bool test_driver_copy_from_directory_64(struct torture_context *tctx,
11484 : struct dcerpc_pipe *p)
11485 : {
11486 0 : return test_driver_copy_from_directory(tctx, p, SPOOLSS_ARCHITECTURE_x64);
11487 : }
11488 :
11489 0 : static bool test_driver_copy_from_directory_32(struct torture_context *tctx,
11490 : struct dcerpc_pipe *p)
11491 : {
11492 0 : return test_driver_copy_from_directory(tctx, p, SPOOLSS_ARCHITECTURE_NT_X86);
11493 : }
11494 :
11495 0 : static bool test_del_driver_all_files(struct torture_context *tctx,
11496 : struct dcerpc_pipe *p)
11497 : {
11498 : struct torture_driver_context *d;
11499 : struct spoolss_StringArray *a;
11500 0 : uint32_t add_flags = APD_COPY_NEW_FILES;
11501 0 : uint32_t delete_flags = DPD_DELETE_ALL_FILES;
11502 0 : struct dcerpc_binding_handle *b = p->binding_handle;
11503 0 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11504 :
11505 0 : d = talloc_zero(tctx, struct torture_driver_context);
11506 :
11507 0 : d->local.environment = talloc_strdup(d, SPOOLSS_ARCHITECTURE_x64);
11508 0 : d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
11509 :
11510 0 : d->ex = true;
11511 0 : d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11512 0 : d->info8.driver_name = TORTURE_DRIVER_DELETER;
11513 0 : d->info8.architecture = d->local.environment;
11514 0 : d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
11515 0 : d->info8.data_file = talloc_strdup(d, "cups6.ppd");
11516 0 : d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
11517 0 : d->info8.help_file = talloc_strdup(d, "pscript.hlp");
11518 :
11519 0 : a = talloc_zero(d, struct spoolss_StringArray);
11520 0 : a->string = talloc_zero_array(a, const char *, 3);
11521 0 : a->string[0] = talloc_strdup(a->string, "cups6.inf");
11522 0 : a->string[1] = talloc_strdup(a->string, "cups6.ini");
11523 :
11524 0 : d->info8.dependent_files = a;
11525 :
11526 0 : torture_assert(tctx,
11527 : fillup_printserver_info(tctx, p, d),
11528 : "failed to fillup printserver info");
11529 :
11530 0 : if (!directory_exist(d->local.driver_directory)) {
11531 0 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11532 : }
11533 :
11534 0 : torture_assert(tctx,
11535 : upload_printer_driver(tctx, dcerpc_server_name(p), d),
11536 : "failed to upload printer driver");
11537 :
11538 0 : torture_assert(tctx,
11539 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &d->info8, add_flags, true, NULL),
11540 : "failed to add driver");
11541 :
11542 0 : torture_assert(tctx,
11543 : test_DeletePrinterDriverEx(tctx, b, server_name_slash,
11544 : d->info8.driver_name,
11545 : d->info8.architecture,
11546 : delete_flags,
11547 : d->info8.version),
11548 : "failed to delete driver");
11549 :
11550 0 : torture_assert(tctx,
11551 : check_printer_driver_files(tctx, dcerpc_server_name(p), d, false),
11552 : "printer driver file check failed");
11553 :
11554 0 : talloc_free(d);
11555 0 : return true;
11556 : }
11557 :
11558 0 : static bool test_del_driver_unused_files(struct torture_context *tctx,
11559 : struct dcerpc_pipe *p)
11560 : {
11561 : struct torture_driver_context *d1;
11562 : struct torture_driver_context *d2;
11563 0 : uint32_t add_flags = APD_COPY_NEW_FILES;
11564 0 : struct dcerpc_binding_handle *b = p->binding_handle;
11565 0 : const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
11566 :
11567 0 : d1 = talloc_zero(tctx, struct torture_driver_context);
11568 0 : d1->ex = true;
11569 :
11570 0 : d1->local.environment = talloc_strdup(d1, SPOOLSS_ARCHITECTURE_x64);
11571 0 : d1->local.driver_directory = talloc_strdup(d1, "/usr/share/cups/drivers/x64");
11572 :
11573 0 : d1->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11574 0 : d1->info8.driver_name = TORTURE_DRIVER_DELETER;
11575 0 : d1->info8.architecture = NULL;
11576 0 : d1->info8.driver_path = talloc_strdup(d1, "pscript5.dll");
11577 0 : d1->info8.data_file = talloc_strdup(d1, "cups6.ppd");
11578 0 : d1->info8.config_file = talloc_strdup(d1, "cupsui6.dll");
11579 0 : d1->info8.help_file = talloc_strdup(d1, "pscript.hlp");
11580 0 : d1->info8.architecture = d1->local.environment;
11581 :
11582 0 : d2 = talloc_zero(tctx, struct torture_driver_context);
11583 0 : d2->ex = true;
11584 :
11585 0 : d2->local.environment = talloc_strdup(d2, SPOOLSS_ARCHITECTURE_x64);
11586 0 : d2->local.driver_directory = talloc_strdup(d2, "/usr/share/cups/drivers/x64");
11587 :
11588 0 : d2->info8.version = SPOOLSS_DRIVER_VERSION_200X;
11589 0 : d2->info8.driver_name = TORTURE_DRIVER_DELETERIN;
11590 0 : d2->info8.architecture = NULL;
11591 0 : d2->info8.driver_path = talloc_strdup(d2, "pscript5.dll"); /* overlapping */
11592 0 : d2->info8.data_file = talloc_strdup(d2, "cupsps6.dll");
11593 0 : d2->info8.config_file = talloc_strdup(d2, "cups6.ini");
11594 0 : d2->info8.help_file = talloc_strdup(d2, "pscript.hlp"); /* overlapping */
11595 0 : d2->info8.architecture = d2->local.environment;
11596 :
11597 0 : torture_assert(tctx,
11598 : fillup_printserver_info(tctx, p, d1),
11599 : "failed to fillup printserver info");
11600 0 : torture_assert(tctx,
11601 : fillup_printserver_info(tctx, p, d2),
11602 : "failed to fillup printserver info");
11603 :
11604 0 : if (!directory_exist(d1->local.driver_directory)) {
11605 0 : torture_skip(tctx, "Skipping Printer Driver test as no local driver is available");
11606 : }
11607 :
11608 0 : torture_assert(tctx,
11609 : upload_printer_driver(tctx, dcerpc_server_name(p), d1),
11610 : "failed to upload printer driver");
11611 0 : torture_assert(tctx,
11612 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &d1->info8, add_flags, true, NULL),
11613 : "failed to add driver");
11614 :
11615 0 : torture_assert(tctx,
11616 : upload_printer_driver(tctx, dcerpc_server_name(p), d2),
11617 : "failed to upload printer driver");
11618 0 : torture_assert(tctx,
11619 : test_AddPrinterDriver_args_level_3(tctx, b, server_name_slash, &d2->info8, add_flags, true, NULL),
11620 : "failed to add driver");
11621 :
11622 : /* some files are in use by a separate driver, should fail */
11623 0 : torture_assert(tctx,
11624 : test_DeletePrinterDriverEx_exp(tctx, b, server_name_slash,
11625 : d1->info8.driver_name,
11626 : d1->info8.architecture,
11627 : DPD_DELETE_ALL_FILES,
11628 : d1->info8.version,
11629 : WERR_PRINTER_DRIVER_IN_USE),
11630 : "invalid delete driver response");
11631 :
11632 : /* should only delete files not in use by other driver */
11633 0 : torture_assert(tctx,
11634 : test_DeletePrinterDriverEx_exp(tctx, b, server_name_slash,
11635 : d1->info8.driver_name,
11636 : d1->info8.architecture,
11637 : DPD_DELETE_UNUSED_FILES,
11638 : d1->info8.version,
11639 : WERR_OK),
11640 : "failed to delete driver (unused files)");
11641 :
11642 : /* check non-overlapping were deleted */
11643 0 : d1->info8.driver_path = NULL;
11644 0 : d1->info8.help_file = NULL;
11645 0 : torture_assert(tctx,
11646 : check_printer_driver_files(tctx, dcerpc_server_name(p), d1, false),
11647 : "printer driver file check failed");
11648 : /* d2 files should be uneffected */
11649 0 : torture_assert(tctx,
11650 : check_printer_driver_files(tctx, dcerpc_server_name(p), d2, true),
11651 : "printer driver file check failed");
11652 :
11653 0 : torture_assert(tctx,
11654 : test_DeletePrinterDriverEx_exp(tctx, b, server_name_slash,
11655 : d2->info8.driver_name,
11656 : d2->info8.architecture,
11657 : DPD_DELETE_ALL_FILES,
11658 : d2->info8.version,
11659 : WERR_OK),
11660 : "failed to delete driver");
11661 :
11662 0 : torture_assert(tctx,
11663 : check_printer_driver_files(tctx, dcerpc_server_name(p), d2, false),
11664 : "printer driver file check failed");
11665 :
11666 0 : talloc_free(d1);
11667 0 : talloc_free(d2);
11668 0 : return true;
11669 : }
11670 :
11671 964 : struct torture_suite *torture_rpc_spoolss_driver(TALLOC_CTX *mem_ctx)
11672 : {
11673 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss.driver");
11674 :
11675 964 : struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
11676 : "driver", &ndr_table_spoolss);
11677 964 : torture_rpc_tcase_add_test(tcase, "add_driver_64", test_add_driver_64);
11678 964 : torture_rpc_tcase_add_test(tcase, "add_driver_ex_64", test_add_driver_ex_64);
11679 :
11680 964 : torture_rpc_tcase_add_test(tcase, "add_driver_32", test_add_driver_32);
11681 964 : torture_rpc_tcase_add_test(tcase, "add_driver_ex_32", test_add_driver_ex_32);
11682 :
11683 964 : torture_rpc_tcase_add_test(tcase, "add_driver_adobe", test_add_driver_adobe);
11684 :
11685 964 : torture_rpc_tcase_add_test(tcase, "add_driver_adobe_cupsaddsmb", test_add_driver_adobe_cupsaddsmb);
11686 :
11687 964 : torture_rpc_tcase_add_test(tcase, "add_driver_timestamps", test_add_driver_timestamps);
11688 :
11689 964 : torture_rpc_tcase_add_test(tcase, "multiple_drivers", test_multiple_drivers);
11690 :
11691 964 : torture_rpc_tcase_add_test(tcase,
11692 : "test_driver_copy_from_directory_64",
11693 : test_driver_copy_from_directory_64);
11694 :
11695 964 : torture_rpc_tcase_add_test(tcase,
11696 : "test_driver_copy_from_directory_32",
11697 : test_driver_copy_from_directory_32);
11698 :
11699 964 : torture_rpc_tcase_add_test(tcase, "del_driver_all_files", test_del_driver_all_files);
11700 :
11701 964 : torture_rpc_tcase_add_test(tcase, "del_driver_unused_files", test_del_driver_unused_files);
11702 :
11703 964 : return suite;
11704 : }
|