Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : test suite for spoolss rpc operations as performed by various win versions
4 :
5 : Copyright (C) Kai Blin 2007
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "torture/rpc/torture_rpc.h"
23 : #include "librpc/gen_ndr/ndr_spoolss_c.h"
24 : #include "librpc/gen_ndr/ndr_misc.h"
25 : #include "param/param.h"
26 :
27 : struct test_spoolss_win_context {
28 : /* EnumPrinters */
29 : uint32_t printer_count;
30 : union spoolss_PrinterInfo *printer_info;
31 : union spoolss_PrinterInfo *current_info;
32 :
33 : /* EnumPrinterKeys */
34 : const char **printer_keys;
35 :
36 : bool printer_has_driver;
37 : };
38 :
39 : /* This is a convenience function for all OpenPrinterEx calls */
40 68 : static bool test_OpenPrinterEx(struct torture_context *tctx,
41 : struct dcerpc_binding_handle *b,
42 : struct policy_handle *handle,
43 : const char *printer_name,
44 : uint32_t access_mask)
45 : {
46 0 : NTSTATUS status;
47 0 : struct spoolss_OpenPrinterEx op;
48 0 : struct spoolss_UserLevel1 ul_1;
49 :
50 68 : torture_comment(tctx, "Opening printer '%s'\n", printer_name);
51 :
52 68 : op.in.printername = talloc_strdup(tctx, printer_name);
53 68 : op.in.datatype = NULL;
54 68 : op.in.devmode_ctr.devmode = NULL;
55 68 : op.in.access_mask = access_mask;
56 68 : op.in.userlevel_ctr.level = 1;
57 68 : op.in.userlevel_ctr.user_info.level1 = &ul_1;
58 68 : op.out.handle = handle;
59 :
60 68 : ul_1.size = 1234;
61 68 : ul_1.client = "\\clientname";
62 68 : ul_1.user = "username";
63 68 : ul_1.build = 1;
64 68 : ul_1.major = 2;
65 68 : ul_1.minor = 3;
66 68 : ul_1.processor = 4567;
67 :
68 68 : status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &op);
69 68 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
70 68 : torture_assert_werr_ok(tctx, op.out.result, "OpenPrinterEx failed");
71 :
72 68 : return true;
73 : }
74 :
75 8 : static bool test_OpenPrinterAsAdmin(struct torture_context *tctx,
76 : struct dcerpc_binding_handle *b,
77 : const char *printername)
78 : {
79 0 : NTSTATUS status;
80 0 : struct spoolss_OpenPrinterEx op;
81 0 : struct spoolss_ClosePrinter cp;
82 0 : struct spoolss_UserLevel1 ul_1;
83 0 : struct policy_handle handle;
84 :
85 8 : ul_1.size = 1234;
86 8 : ul_1.client = "\\clientname";
87 8 : ul_1.user = "username";
88 8 : ul_1.build = 1;
89 8 : ul_1.major = 2;
90 8 : ul_1.minor = 3;
91 8 : ul_1.processor = 4567;
92 :
93 8 : op.in.printername = talloc_strdup(tctx, printername);
94 8 : op.in.datatype = NULL;
95 8 : op.in.devmode_ctr.devmode = NULL;
96 8 : op.in.access_mask = SERVER_ALL_ACCESS;
97 8 : op.in.userlevel_ctr.level = 1;
98 8 : op.in.userlevel_ctr.user_info.level1 = &ul_1;
99 8 : op.out.handle = &handle;
100 :
101 8 : cp.in.handle = &handle;
102 8 : cp.out.handle = &handle;
103 :
104 8 : torture_comment(tctx, "Testing OpenPrinterEx(%s) with admin rights\n",
105 : op.in.printername);
106 :
107 8 : status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &op);
108 :
109 8 : if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(op.out.result)) {
110 4 : status = dcerpc_spoolss_ClosePrinter_r(b, tctx, &cp);
111 4 : torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
112 : }
113 :
114 8 : return true;
115 : }
116 :
117 :
118 :
119 : /* This replicates the opening sequence of OpenPrinterEx calls XP does */
120 4 : static bool test_OpenPrinterSequence(struct torture_context *tctx,
121 : struct dcerpc_pipe *p,
122 : struct policy_handle *handle)
123 : {
124 0 : bool ret;
125 4 : char *printername = talloc_asprintf(tctx, "\\\\%s",
126 : dcerpc_server_name(p));
127 4 : struct dcerpc_binding_handle *b = p->binding_handle;
128 :
129 : /* First, see if we can open the printer read_only */
130 4 : ret = test_OpenPrinterEx(tctx, b, handle, printername, 0);
131 4 : torture_assert(tctx, ret == true, "OpenPrinterEx failed.");
132 :
133 4 : ret = test_ClosePrinter(tctx, b, handle);
134 4 : torture_assert(tctx, ret, "ClosePrinter failed");
135 :
136 : /* Now let's see if we have admin rights to it. */
137 4 : ret = test_OpenPrinterAsAdmin(tctx, b, printername);
138 4 : torture_assert(tctx, ret == true,
139 : "OpenPrinterEx as admin failed unexpectedly.");
140 :
141 4 : ret = test_OpenPrinterEx(tctx, b, handle, printername, SERVER_EXECUTE);
142 4 : torture_assert(tctx, ret == true, "OpenPrinterEx failed.");
143 :
144 4 : return true;
145 : }
146 :
147 16 : static bool test_GetPrinterData(struct torture_context *tctx,
148 : struct dcerpc_binding_handle *b,
149 : struct policy_handle *handle,
150 : const char *value_name,
151 : WERROR expected_werr,
152 : uint32_t expected_value)
153 : {
154 0 : NTSTATUS status;
155 0 : struct spoolss_GetPrinterData gpd;
156 0 : uint32_t needed;
157 0 : enum winreg_Type type;
158 16 : uint8_t *data = talloc_zero_array(tctx, uint8_t, 4);
159 :
160 16 : torture_comment(tctx, "Testing GetPrinterData(%s).\n", value_name);
161 16 : gpd.in.handle = handle;
162 16 : gpd.in.value_name = value_name;
163 16 : gpd.in.offered = 4;
164 16 : gpd.out.needed = &needed;
165 16 : gpd.out.type = &type;
166 16 : gpd.out.data = data;
167 :
168 16 : status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &gpd);
169 16 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed.");
170 16 : torture_assert_werr_equal(tctx, gpd.out.result, expected_werr,
171 : "GetPrinterData did not return expected error value.");
172 :
173 16 : if (W_ERROR_IS_OK(expected_werr)) {
174 8 : uint32_t value = IVAL(data, 0);
175 8 : torture_assert_int_equal(tctx, value,
176 : expected_value,
177 : talloc_asprintf(tctx, "GetPrinterData for %s did not return expected value.", value_name));
178 : }
179 16 : return true;
180 : }
181 :
182 8 : static bool test_EnumPrinters(struct torture_context *tctx,
183 : struct dcerpc_pipe *p,
184 : struct test_spoolss_win_context *ctx,
185 : uint32_t initial_blob_size)
186 : {
187 0 : NTSTATUS status;
188 0 : struct spoolss_EnumPrinters ep;
189 8 : DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
190 0 : uint32_t needed;
191 0 : uint32_t count;
192 0 : union spoolss_PrinterInfo *info;
193 8 : struct dcerpc_binding_handle *b = p->binding_handle;
194 :
195 8 : ep.in.flags = PRINTER_ENUM_NAME;
196 8 : ep.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
197 8 : ep.in.level = 2;
198 8 : ep.in.buffer = &blob;
199 8 : ep.in.offered = initial_blob_size;
200 8 : ep.out.needed = &needed;
201 8 : ep.out.count = &count;
202 8 : ep.out.info = &info;
203 :
204 8 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &ep);
205 8 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed.");
206 :
207 8 : if (W_ERROR_EQUAL(ep.out.result, WERR_INSUFFICIENT_BUFFER)) {
208 8 : blob = data_blob_talloc_zero(ctx, needed);
209 8 : ep.in.buffer = &blob;
210 8 : ep.in.offered = needed;
211 8 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &ep);
212 8 : torture_assert_ntstatus_ok(tctx, status,"EnumPrinters failed.");
213 : }
214 :
215 8 : torture_assert_werr_ok(tctx, ep.out.result, "EnumPrinters failed.");
216 :
217 8 : ctx->printer_count = count;
218 8 : ctx->printer_info = info;
219 :
220 8 : torture_comment(tctx, "Found %d printer(s).\n", ctx->printer_count);
221 :
222 8 : return true;
223 : }
224 :
225 40 : static bool test_GetPrinter(struct torture_context *tctx,
226 : struct dcerpc_binding_handle *b,
227 : struct policy_handle *handle,
228 : struct test_spoolss_win_context *ctx,
229 : uint32_t level,
230 : uint32_t initial_blob_size)
231 : {
232 0 : NTSTATUS status;
233 0 : struct spoolss_GetPrinter gp;
234 40 : DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
235 0 : uint32_t needed;
236 :
237 40 : torture_comment(tctx, "Test GetPrinter level %d\n", level);
238 :
239 40 : gp.in.handle = handle;
240 40 : gp.in.level = level;
241 40 : gp.in.buffer = (initial_blob_size == 0)?NULL:&blob;
242 40 : gp.in.offered = initial_blob_size;
243 40 : gp.out.needed = &needed;
244 :
245 40 : status = dcerpc_spoolss_GetPrinter_r(b, tctx, &gp);
246 40 : torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
247 :
248 40 : if (W_ERROR_EQUAL(gp.out.result, WERR_INSUFFICIENT_BUFFER)) {
249 24 : blob = data_blob_talloc_zero(ctx, needed);
250 24 : gp.in.buffer = &blob;
251 24 : gp.in.offered = needed;
252 24 : status = dcerpc_spoolss_GetPrinter_r(b, tctx, &gp);
253 24 : torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
254 : }
255 :
256 40 : torture_assert_werr_ok(tctx, gp.out.result, "GetPrinter failed");
257 :
258 40 : ctx->current_info = gp.out.info;
259 :
260 40 : if (level == 2 && gp.out.info) {
261 64 : ctx->printer_has_driver = gp.out.info->info2.drivername &&
262 32 : strlen(gp.out.info->info2.drivername);
263 : }
264 :
265 40 : return true;
266 : }
267 :
268 4 : static bool test_EnumJobs(struct torture_context *tctx,
269 : struct dcerpc_binding_handle *b,
270 : struct policy_handle *handle)
271 : {
272 0 : NTSTATUS status;
273 0 : struct spoolss_EnumJobs ej;
274 4 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 1024);
275 0 : uint32_t needed;
276 0 : uint32_t count;
277 0 : union spoolss_JobInfo *info;
278 :
279 4 : torture_comment(tctx, "Test EnumJobs\n");
280 :
281 4 : ZERO_STRUCT(ej);
282 4 : ej.in.handle = handle;
283 4 : ej.in.firstjob = 0;
284 4 : ej.in.numjobs = 0;
285 4 : ej.in.level = 2;
286 4 : ej.in.buffer = &blob;
287 4 : ej.in.offered = 1024;
288 4 : ej.out.needed = &needed;
289 4 : ej.out.count = &count;
290 4 : ej.out.info = &info;
291 :
292 4 : status = dcerpc_spoolss_EnumJobs_r(b, tctx, &ej);
293 4 : torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
294 4 : if (W_ERROR_EQUAL(ej.out.result, WERR_INSUFFICIENT_BUFFER)) {
295 0 : blob = data_blob_talloc_zero(tctx, needed);
296 0 : ej.in.offered = needed;
297 0 : ej.in.buffer = &blob;
298 0 : status = dcerpc_spoolss_EnumJobs_r(b, tctx, &ej);
299 0 : torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
300 : }
301 4 : torture_assert_werr_ok(tctx, ej.out.result, "EnumJobs failed");
302 :
303 4 : return true;
304 : }
305 :
306 4 : static bool test_GetPrinterDriver2(struct torture_context *tctx,
307 : struct dcerpc_binding_handle *b,
308 : struct test_spoolss_win_context *ctx,
309 : struct policy_handle *handle)
310 : {
311 0 : NTSTATUS status;
312 0 : struct spoolss_GetPrinterDriver2 gpd2;
313 4 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 87424);
314 0 : uint32_t needed;
315 0 : uint32_t server_major_version;
316 0 : uint32_t server_minor_version;
317 :
318 4 : torture_comment(tctx, "Testing GetPrinterDriver2\n");
319 :
320 4 : gpd2.in.handle = handle;
321 4 : gpd2.in.architecture = "Windows NT x86";
322 4 : gpd2.in.level = 101;
323 4 : gpd2.in.buffer = &blob;
324 4 : gpd2.in.offered = 87424;
325 4 : gpd2.in.client_major_version = 3;
326 4 : gpd2.in.client_minor_version = 0;
327 4 : gpd2.out.needed = &needed;
328 4 : gpd2.out.server_major_version = &server_major_version;
329 4 : gpd2.out.server_minor_version = &server_minor_version;
330 :
331 4 : status = dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &gpd2);
332 4 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterDriver2 failed");
333 :
334 4 : if (ctx->printer_has_driver) {
335 0 : torture_assert_werr_ok(tctx, gpd2.out.result,
336 : "GetPrinterDriver2 failed.");
337 : }
338 :
339 4 : return true;
340 : }
341 :
342 4 : static bool test_EnumForms(struct torture_context *tctx,
343 : struct dcerpc_binding_handle *b,
344 : struct policy_handle *handle,
345 : uint32_t initial_blob_size)
346 : {
347 0 : NTSTATUS status;
348 0 : struct spoolss_EnumForms ef;
349 4 : DATA_BLOB blob = data_blob_talloc_zero(tctx, initial_blob_size);
350 0 : uint32_t needed;
351 0 : uint32_t count;
352 0 : union spoolss_FormInfo *info;
353 :
354 4 : torture_comment(tctx, "Testing EnumForms\n");
355 :
356 4 : ef.in.handle = handle;
357 4 : ef.in.level = 1;
358 4 : ef.in.buffer = (initial_blob_size == 0)?NULL:&blob;
359 4 : ef.in.offered = initial_blob_size;
360 4 : ef.out.needed = &needed;
361 4 : ef.out.count = &count;
362 4 : ef.out.info = &info;
363 :
364 4 : status = dcerpc_spoolss_EnumForms_r(b, tctx, &ef);
365 4 : torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
366 :
367 4 : if (W_ERROR_EQUAL(ef.out.result, WERR_INSUFFICIENT_BUFFER)) {
368 4 : blob = data_blob_talloc_zero(tctx, needed);
369 4 : ef.in.buffer = &blob;
370 4 : ef.in.offered = needed;
371 4 : status = dcerpc_spoolss_EnumForms_r(b, tctx, &ef);
372 4 : torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
373 : }
374 :
375 4 : torture_assert_werr_ok(tctx, ef.out.result, "EnumForms failed");
376 :
377 4 : return true;
378 : }
379 :
380 20 : static bool test_EnumPrinterKey(struct torture_context *tctx,
381 : struct dcerpc_binding_handle *b,
382 : struct policy_handle *handle,
383 : const char* key,
384 : struct test_spoolss_win_context *ctx)
385 : {
386 0 : NTSTATUS status;
387 0 : struct spoolss_EnumPrinterKey epk;
388 20 : uint32_t needed = 0;
389 0 : union spoolss_KeyNames key_buffer;
390 0 : uint32_t _ndr_size;
391 :
392 20 : torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key);
393 :
394 20 : epk.in.handle = handle;
395 20 : epk.in.key_name = talloc_strdup(tctx, key);
396 20 : epk.in.offered = 0;
397 20 : epk.out.needed = &needed;
398 20 : epk.out.key_buffer = &key_buffer;
399 20 : epk.out._ndr_size = &_ndr_size;
400 :
401 20 : status = dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &epk);
402 20 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed");
403 :
404 20 : if (W_ERROR_EQUAL(epk.out.result, WERR_MORE_DATA)) {
405 20 : epk.in.offered = needed;
406 20 : status = dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &epk);
407 20 : torture_assert_ntstatus_ok(tctx, status,
408 : "EnumPrinterKey failed");
409 : }
410 :
411 20 : torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed");
412 :
413 20 : ctx->printer_keys = key_buffer.string_array;
414 :
415 20 : return true;
416 : }
417 :
418 20 : static bool test_EnumPrinterDataEx(struct torture_context *tctx,
419 : struct dcerpc_binding_handle *b,
420 : struct policy_handle *handle,
421 : const char *key,
422 : uint32_t initial_blob_size,
423 : WERROR expected_error)
424 : {
425 0 : NTSTATUS status;
426 0 : struct spoolss_EnumPrinterDataEx epde;
427 0 : struct spoolss_PrinterEnumValues *info;
428 0 : uint32_t needed;
429 0 : uint32_t count;
430 :
431 20 : torture_comment(tctx, "Testing EnumPrinterDataEx(%s)\n", key);
432 :
433 20 : epde.in.handle = handle;
434 20 : epde.in.key_name = talloc_strdup(tctx, key);
435 20 : epde.in.offered = 0;
436 20 : epde.out.needed = &needed;
437 20 : epde.out.count = &count;
438 20 : epde.out.info = &info;
439 :
440 20 : status = dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &epde);
441 20 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed.");
442 20 : if (W_ERROR_EQUAL(epde.out.result, WERR_MORE_DATA)) {
443 4 : epde.in.offered = needed;
444 4 : status = dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &epde);
445 4 : torture_assert_ntstatus_ok(tctx, status,
446 : "EnumPrinterDataEx failed.");
447 : }
448 :
449 20 : torture_assert_werr_equal(tctx, epde.out.result, expected_error,
450 : "EnumPrinterDataEx failed.");
451 :
452 20 : return true;
453 : }
454 :
455 4 : static bool test_WinXP(struct torture_context *tctx, struct dcerpc_pipe *p)
456 : {
457 4 : bool ret = true;
458 0 : struct test_spoolss_win_context *ctx, *tmp_ctx;
459 0 : struct policy_handle handle01, handle02, handle03, handle04;
460 : /* Sometimes a handle stays unused. In order to make this clear in the
461 : * code, the unused_handle structures are used for that. */
462 0 : struct policy_handle unused_handle1, unused_handle2;
463 0 : char *server_name;
464 0 : uint32_t i;
465 4 : struct dcerpc_binding_handle *b = p->binding_handle;
466 :
467 4 : ctx = talloc_zero(tctx, struct test_spoolss_win_context);
468 4 : tmp_ctx = talloc_zero(tctx, struct test_spoolss_win_context);
469 :
470 4 : ret &= test_OpenPrinterSequence(tctx, p, &handle01);
471 8 : ret &= test_GetPrinterData(tctx, b, &handle01,"UISingleJobStatusString",
472 4 : WERR_INVALID_PARAMETER, 0);
473 4 : torture_comment(tctx, "Skip RemoteFindNextPrinterChangeNotifyEx test\n");
474 :
475 4 : server_name = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p));
476 4 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle1, server_name, 0);
477 :
478 4 : ret &= test_EnumPrinters(tctx, p, ctx, 1024);
479 :
480 4 : ret &= test_OpenPrinterEx(tctx, b, &handle02, server_name, 0);
481 4 : ret &= test_GetPrinterData(tctx, b, &handle02, "MajorVersion", WERR_OK,
482 : 3);
483 4 : ret &= test_ClosePrinter(tctx, b, &handle02);
484 :
485 : /* If no printers were found, skip all tests that need a printer */
486 4 : if (ctx->printer_count == 0) {
487 0 : goto end_testWinXP;
488 : }
489 :
490 8 : ret &= test_OpenPrinterEx(tctx, b, &handle02,
491 4 : ctx->printer_info[0].info2.printername,
492 : PRINTER_ACCESS_USE);
493 4 : ret &= test_GetPrinter(tctx, b, &handle02, ctx, 2, 0);
494 :
495 4 : torture_assert_str_equal(tctx, ctx->current_info->info2.printername,
496 : ctx->printer_info[0].info2.printername,
497 : "GetPrinter returned unexpected printername");
498 : /*FIXME: Test more components of the PrinterInfo2 struct */
499 :
500 8 : ret &= test_OpenPrinterEx(tctx, b, &handle03,
501 4 : ctx->printer_info[0].info2.printername, 0);
502 4 : ret &= test_GetPrinter(tctx, b, &handle03, ctx, 0, 1164);
503 4 : ret &= test_GetPrinter(tctx, b, &handle03, ctx, 2, 0);
504 :
505 8 : ret &= test_OpenPrinterEx(tctx, b, &handle04,
506 4 : ctx->printer_info[0].info2.printername, 0);
507 4 : ret &= test_GetPrinter(tctx, b, &handle04, ctx, 2, 0);
508 4 : ret &= test_ClosePrinter(tctx, b, &handle04);
509 :
510 8 : ret &= test_OpenPrinterEx(tctx, b, &handle04,
511 4 : ctx->printer_info[0].info2.printername, 0);
512 4 : ret &= test_GetPrinter(tctx, b, &handle04, ctx, 2, 4096);
513 4 : ret &= test_ClosePrinter(tctx, b, &handle04);
514 :
515 8 : ret &= test_OpenPrinterAsAdmin(tctx, b,
516 4 : ctx->printer_info[0].info2.printername);
517 :
518 8 : ret &= test_OpenPrinterEx(tctx, b, &handle04,
519 4 : ctx->printer_info[0].info2.printername, PRINTER_READ);
520 8 : ret &= test_GetPrinterData(tctx, b, &handle04,"UISingleJobStatusString",
521 4 : WERR_FILE_NOT_FOUND, 0);
522 4 : torture_comment(tctx, "Skip RemoteFindNextPrinterChangeNotifyEx test\n");
523 :
524 8 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
525 4 : ctx->printer_info[0].info2.printername, 0);
526 :
527 4 : ret &= test_EnumJobs(tctx, b, &handle04);
528 4 : ret &= test_GetPrinter(tctx, b, &handle04, ctx, 2, 4096);
529 :
530 4 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
531 4 : ret &= test_ClosePrinter(tctx, b, &handle04);
532 :
533 4 : ret &= test_EnumPrinters(tctx, p, ctx, 1556);
534 4 : ret &= test_GetPrinterDriver2(tctx, b, ctx, &handle03);
535 4 : ret &= test_EnumForms(tctx, b, &handle03, 0);
536 :
537 4 : ret &= test_EnumPrinterKey(tctx, b, &handle03, "", ctx);
538 :
539 20 : for (i=0; ctx->printer_keys && ctx->printer_keys[i] != NULL; i++) {
540 :
541 32 : ret &= test_EnumPrinterKey(tctx, b, &handle03,
542 16 : ctx->printer_keys[i],
543 : tmp_ctx);
544 16 : ret &= test_EnumPrinterDataEx(tctx, b, &handle03,
545 16 : ctx->printer_keys[i], 0,
546 16 : WERR_OK);
547 : }
548 :
549 8 : ret &= test_EnumPrinterDataEx(tctx, b, &handle03, "", 0,
550 4 : WERR_INVALID_PARAMETER);
551 :
552 4 : ret &= test_GetPrinter(tctx, b, &handle03, tmp_ctx, 2, 0);
553 :
554 8 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
555 4 : ctx->printer_info[0].info2.printername, 0);
556 4 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
557 :
558 4 : ret &= test_GetPrinter(tctx, b, &handle03, tmp_ctx, 2, 2556);
559 :
560 8 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
561 4 : ctx->printer_info[0].info2.printername, 0);
562 4 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
563 :
564 8 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
565 4 : ctx->printer_info[0].info2.printername, 0);
566 4 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
567 :
568 4 : ret &= test_GetPrinter(tctx, b, &handle03, tmp_ctx, 7, 0);
569 :
570 8 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
571 4 : ctx->printer_info[0].info2.printername, 0);
572 4 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
573 :
574 4 : ret &= test_ClosePrinter(tctx, b, &handle03);
575 :
576 8 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
577 4 : ctx->printer_info[0].info2.printername, 0);
578 4 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
579 :
580 4 : ret &= test_OpenPrinterEx(tctx, b, &handle03, server_name, 0);
581 8 : ret &= test_GetPrinterData(tctx, b, &handle03, "W3SvcInstalled",
582 4 : WERR_OK, 0);
583 4 : ret &= test_ClosePrinter(tctx, b, &handle03);
584 :
585 4 : ret &= test_ClosePrinter(tctx, b, &unused_handle1);
586 4 : ret &= test_ClosePrinter(tctx, b, &handle02);
587 :
588 8 : ret &= test_OpenPrinterEx(tctx, b, &handle02,
589 4 : ctx->printer_info[0].info2.sharename, 0);
590 4 : ret &= test_GetPrinter(tctx, b, &handle02, tmp_ctx, 2, 0);
591 4 : ret &= test_ClosePrinter(tctx, b, &handle02);
592 :
593 4 : end_testWinXP:
594 4 : ret &= test_ClosePrinter(tctx, b, &handle01);
595 :
596 4 : talloc_free(tmp_ctx);
597 4 : talloc_free(ctx);
598 4 : return ret;
599 : }
600 :
601 2354 : struct torture_suite *torture_rpc_spoolss_win(TALLOC_CTX *mem_ctx)
602 : {
603 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss.win");
604 :
605 2354 : struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
606 : "win", &ndr_table_spoolss);
607 :
608 2354 : torture_rpc_tcase_add_test(tcase, "testWinXP", test_WinXP);
609 :
610 2354 : return suite;
611 : }
612 :
|