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 0 : 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 : NTSTATUS status;
47 : struct spoolss_OpenPrinterEx op;
48 : struct spoolss_UserLevel1 ul_1;
49 :
50 0 : torture_comment(tctx, "Opening printer '%s'\n", printer_name);
51 :
52 0 : op.in.printername = talloc_strdup(tctx, printer_name);
53 0 : op.in.datatype = NULL;
54 0 : op.in.devmode_ctr.devmode = NULL;
55 0 : op.in.access_mask = access_mask;
56 0 : op.in.userlevel_ctr.level = 1;
57 0 : op.in.userlevel_ctr.user_info.level1 = &ul_1;
58 0 : op.out.handle = handle;
59 :
60 0 : ul_1.size = 1234;
61 0 : ul_1.client = "\\clientname";
62 0 : ul_1.user = "username";
63 0 : ul_1.build = 1;
64 0 : ul_1.major = 2;
65 0 : ul_1.minor = 3;
66 0 : ul_1.processor = 4567;
67 :
68 0 : status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &op);
69 0 : torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
70 0 : torture_assert_werr_ok(tctx, op.out.result, "OpenPrinterEx failed");
71 :
72 0 : return true;
73 : }
74 :
75 0 : static bool test_OpenPrinterAsAdmin(struct torture_context *tctx,
76 : struct dcerpc_binding_handle *b,
77 : const char *printername)
78 : {
79 : NTSTATUS status;
80 : struct spoolss_OpenPrinterEx op;
81 : struct spoolss_ClosePrinter cp;
82 : struct spoolss_UserLevel1 ul_1;
83 : struct policy_handle handle;
84 :
85 0 : ul_1.size = 1234;
86 0 : ul_1.client = "\\clientname";
87 0 : ul_1.user = "username";
88 0 : ul_1.build = 1;
89 0 : ul_1.major = 2;
90 0 : ul_1.minor = 3;
91 0 : ul_1.processor = 4567;
92 :
93 0 : op.in.printername = talloc_strdup(tctx, printername);
94 0 : op.in.datatype = NULL;
95 0 : op.in.devmode_ctr.devmode = NULL;
96 0 : op.in.access_mask = SERVER_ALL_ACCESS;
97 0 : op.in.userlevel_ctr.level = 1;
98 0 : op.in.userlevel_ctr.user_info.level1 = &ul_1;
99 0 : op.out.handle = &handle;
100 :
101 0 : cp.in.handle = &handle;
102 0 : cp.out.handle = &handle;
103 :
104 0 : torture_comment(tctx, "Testing OpenPrinterEx(%s) with admin rights\n",
105 : op.in.printername);
106 :
107 0 : status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &op);
108 :
109 0 : if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(op.out.result)) {
110 0 : status = dcerpc_spoolss_ClosePrinter_r(b, tctx, &cp);
111 0 : torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
112 : }
113 :
114 0 : return true;
115 : }
116 :
117 :
118 :
119 : /* This replicates the opening sequence of OpenPrinterEx calls XP does */
120 0 : static bool test_OpenPrinterSequence(struct torture_context *tctx,
121 : struct dcerpc_pipe *p,
122 : struct policy_handle *handle)
123 : {
124 : bool ret;
125 0 : char *printername = talloc_asprintf(tctx, "\\\\%s",
126 : dcerpc_server_name(p));
127 0 : struct dcerpc_binding_handle *b = p->binding_handle;
128 :
129 : /* First, see if we can open the printer read_only */
130 0 : ret = test_OpenPrinterEx(tctx, b, handle, printername, 0);
131 0 : torture_assert(tctx, ret == true, "OpenPrinterEx failed.");
132 :
133 0 : ret = test_ClosePrinter(tctx, b, handle);
134 0 : torture_assert(tctx, ret, "ClosePrinter failed");
135 :
136 : /* Now let's see if we have admin rights to it. */
137 0 : ret = test_OpenPrinterAsAdmin(tctx, b, printername);
138 0 : torture_assert(tctx, ret == true,
139 : "OpenPrinterEx as admin failed unexpectedly.");
140 :
141 0 : ret = test_OpenPrinterEx(tctx, b, handle, printername, SERVER_EXECUTE);
142 0 : torture_assert(tctx, ret == true, "OpenPrinterEx failed.");
143 :
144 0 : return true;
145 : }
146 :
147 0 : 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 : NTSTATUS status;
155 : struct spoolss_GetPrinterData gpd;
156 : uint32_t needed;
157 : enum winreg_Type type;
158 0 : uint8_t *data = talloc_zero_array(tctx, uint8_t, 4);
159 :
160 0 : torture_comment(tctx, "Testing GetPrinterData(%s).\n", value_name);
161 0 : gpd.in.handle = handle;
162 0 : gpd.in.value_name = value_name;
163 0 : gpd.in.offered = 4;
164 0 : gpd.out.needed = &needed;
165 0 : gpd.out.type = &type;
166 0 : gpd.out.data = data;
167 :
168 0 : status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &gpd);
169 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed.");
170 0 : torture_assert_werr_equal(tctx, gpd.out.result, expected_werr,
171 : "GetPrinterData did not return expected error value.");
172 :
173 0 : if (W_ERROR_IS_OK(expected_werr)) {
174 0 : uint32_t value = IVAL(data, 0);
175 0 : 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 0 : return true;
180 : }
181 :
182 0 : 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 : NTSTATUS status;
188 : struct spoolss_EnumPrinters ep;
189 0 : DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
190 : uint32_t needed;
191 : uint32_t count;
192 : union spoolss_PrinterInfo *info;
193 0 : struct dcerpc_binding_handle *b = p->binding_handle;
194 :
195 0 : ep.in.flags = PRINTER_ENUM_NAME;
196 0 : ep.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
197 0 : ep.in.level = 2;
198 0 : ep.in.buffer = &blob;
199 0 : ep.in.offered = initial_blob_size;
200 0 : ep.out.needed = &needed;
201 0 : ep.out.count = &count;
202 0 : ep.out.info = &info;
203 :
204 0 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &ep);
205 0 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed.");
206 :
207 0 : if (W_ERROR_EQUAL(ep.out.result, WERR_INSUFFICIENT_BUFFER)) {
208 0 : blob = data_blob_talloc_zero(ctx, needed);
209 0 : ep.in.buffer = &blob;
210 0 : ep.in.offered = needed;
211 0 : status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &ep);
212 0 : torture_assert_ntstatus_ok(tctx, status,"EnumPrinters failed.");
213 : }
214 :
215 0 : torture_assert_werr_ok(tctx, ep.out.result, "EnumPrinters failed.");
216 :
217 0 : ctx->printer_count = count;
218 0 : ctx->printer_info = info;
219 :
220 0 : torture_comment(tctx, "Found %d printer(s).\n", ctx->printer_count);
221 :
222 0 : return true;
223 : }
224 :
225 0 : 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 : NTSTATUS status;
233 : struct spoolss_GetPrinter gp;
234 0 : DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
235 : uint32_t needed;
236 :
237 0 : torture_comment(tctx, "Test GetPrinter level %d\n", level);
238 :
239 0 : gp.in.handle = handle;
240 0 : gp.in.level = level;
241 0 : gp.in.buffer = (initial_blob_size == 0)?NULL:&blob;
242 0 : gp.in.offered = initial_blob_size;
243 0 : gp.out.needed = &needed;
244 :
245 0 : status = dcerpc_spoolss_GetPrinter_r(b, tctx, &gp);
246 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
247 :
248 0 : if (W_ERROR_EQUAL(gp.out.result, WERR_INSUFFICIENT_BUFFER)) {
249 0 : blob = data_blob_talloc_zero(ctx, needed);
250 0 : gp.in.buffer = &blob;
251 0 : gp.in.offered = needed;
252 0 : status = dcerpc_spoolss_GetPrinter_r(b, tctx, &gp);
253 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
254 : }
255 :
256 0 : torture_assert_werr_ok(tctx, gp.out.result, "GetPrinter failed");
257 :
258 0 : ctx->current_info = gp.out.info;
259 :
260 0 : if (level == 2 && gp.out.info) {
261 0 : ctx->printer_has_driver = gp.out.info->info2.drivername &&
262 0 : strlen(gp.out.info->info2.drivername);
263 : }
264 :
265 0 : return true;
266 : }
267 :
268 0 : static bool test_EnumJobs(struct torture_context *tctx,
269 : struct dcerpc_binding_handle *b,
270 : struct policy_handle *handle)
271 : {
272 : NTSTATUS status;
273 : struct spoolss_EnumJobs ej;
274 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 1024);
275 : uint32_t needed;
276 : uint32_t count;
277 : union spoolss_JobInfo *info;
278 :
279 0 : torture_comment(tctx, "Test EnumJobs\n");
280 :
281 0 : ZERO_STRUCT(ej);
282 0 : ej.in.handle = handle;
283 0 : ej.in.firstjob = 0;
284 0 : ej.in.numjobs = 0;
285 0 : ej.in.level = 2;
286 0 : ej.in.buffer = &blob;
287 0 : ej.in.offered = 1024;
288 0 : ej.out.needed = &needed;
289 0 : ej.out.count = &count;
290 0 : ej.out.info = &info;
291 :
292 0 : status = dcerpc_spoolss_EnumJobs_r(b, tctx, &ej);
293 0 : torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
294 0 : 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 0 : torture_assert_werr_ok(tctx, ej.out.result, "EnumJobs failed");
302 :
303 0 : return true;
304 : }
305 :
306 0 : 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 : NTSTATUS status;
312 : struct spoolss_GetPrinterDriver2 gpd2;
313 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, 87424);
314 : uint32_t needed;
315 : uint32_t server_major_version;
316 : uint32_t server_minor_version;
317 :
318 0 : torture_comment(tctx, "Testing GetPrinterDriver2\n");
319 :
320 0 : gpd2.in.handle = handle;
321 0 : gpd2.in.architecture = "Windows NT x86";
322 0 : gpd2.in.level = 101;
323 0 : gpd2.in.buffer = &blob;
324 0 : gpd2.in.offered = 87424;
325 0 : gpd2.in.client_major_version = 3;
326 0 : gpd2.in.client_minor_version = 0;
327 0 : gpd2.out.needed = &needed;
328 0 : gpd2.out.server_major_version = &server_major_version;
329 0 : gpd2.out.server_minor_version = &server_minor_version;
330 :
331 0 : status = dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &gpd2);
332 0 : torture_assert_ntstatus_ok(tctx, status, "GetPrinterDriver2 failed");
333 :
334 0 : if (ctx->printer_has_driver) {
335 0 : torture_assert_werr_ok(tctx, gpd2.out.result,
336 : "GetPrinterDriver2 failed.");
337 : }
338 :
339 0 : return true;
340 : }
341 :
342 0 : 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 : NTSTATUS status;
348 : struct spoolss_EnumForms ef;
349 0 : DATA_BLOB blob = data_blob_talloc_zero(tctx, initial_blob_size);
350 : uint32_t needed;
351 : uint32_t count;
352 : union spoolss_FormInfo *info;
353 :
354 0 : torture_comment(tctx, "Testing EnumForms\n");
355 :
356 0 : ef.in.handle = handle;
357 0 : ef.in.level = 1;
358 0 : ef.in.buffer = (initial_blob_size == 0)?NULL:&blob;
359 0 : ef.in.offered = initial_blob_size;
360 0 : ef.out.needed = &needed;
361 0 : ef.out.count = &count;
362 0 : ef.out.info = &info;
363 :
364 0 : status = dcerpc_spoolss_EnumForms_r(b, tctx, &ef);
365 0 : torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
366 :
367 0 : if (W_ERROR_EQUAL(ef.out.result, WERR_INSUFFICIENT_BUFFER)) {
368 0 : blob = data_blob_talloc_zero(tctx, needed);
369 0 : ef.in.buffer = &blob;
370 0 : ef.in.offered = needed;
371 0 : status = dcerpc_spoolss_EnumForms_r(b, tctx, &ef);
372 0 : torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
373 : }
374 :
375 0 : torture_assert_werr_ok(tctx, ef.out.result, "EnumForms failed");
376 :
377 0 : return true;
378 : }
379 :
380 0 : 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 : NTSTATUS status;
387 : struct spoolss_EnumPrinterKey epk;
388 0 : uint32_t needed = 0;
389 : union spoolss_KeyNames key_buffer;
390 : uint32_t _ndr_size;
391 :
392 0 : torture_comment(tctx, "Testing EnumPrinterKey(%s)\n", key);
393 :
394 0 : epk.in.handle = handle;
395 0 : epk.in.key_name = talloc_strdup(tctx, key);
396 0 : epk.in.offered = 0;
397 0 : epk.out.needed = &needed;
398 0 : epk.out.key_buffer = &key_buffer;
399 0 : epk.out._ndr_size = &_ndr_size;
400 :
401 0 : status = dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &epk);
402 0 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinterKey failed");
403 :
404 0 : if (W_ERROR_EQUAL(epk.out.result, WERR_MORE_DATA)) {
405 0 : epk.in.offered = needed;
406 0 : status = dcerpc_spoolss_EnumPrinterKey_r(b, tctx, &epk);
407 0 : torture_assert_ntstatus_ok(tctx, status,
408 : "EnumPrinterKey failed");
409 : }
410 :
411 0 : torture_assert_werr_ok(tctx, epk.out.result, "EnumPrinterKey failed");
412 :
413 0 : ctx->printer_keys = key_buffer.string_array;
414 :
415 0 : return true;
416 : }
417 :
418 0 : 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 : NTSTATUS status;
426 : struct spoolss_EnumPrinterDataEx epde;
427 : struct spoolss_PrinterEnumValues *info;
428 : uint32_t needed;
429 : uint32_t count;
430 :
431 0 : torture_comment(tctx, "Testing EnumPrinterDataEx(%s)\n", key);
432 :
433 0 : epde.in.handle = handle;
434 0 : epde.in.key_name = talloc_strdup(tctx, key);
435 0 : epde.in.offered = 0;
436 0 : epde.out.needed = &needed;
437 0 : epde.out.count = &count;
438 0 : epde.out.info = &info;
439 :
440 0 : status = dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &epde);
441 0 : torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed.");
442 0 : if (W_ERROR_EQUAL(epde.out.result, WERR_MORE_DATA)) {
443 0 : epde.in.offered = needed;
444 0 : status = dcerpc_spoolss_EnumPrinterDataEx_r(b, tctx, &epde);
445 0 : torture_assert_ntstatus_ok(tctx, status,
446 : "EnumPrinterDataEx failed.");
447 : }
448 :
449 0 : torture_assert_werr_equal(tctx, epde.out.result, expected_error,
450 : "EnumPrinterDataEx failed.");
451 :
452 0 : return true;
453 : }
454 :
455 0 : static bool test_WinXP(struct torture_context *tctx, struct dcerpc_pipe *p)
456 : {
457 0 : bool ret = true;
458 : struct test_spoolss_win_context *ctx, *tmp_ctx;
459 : 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 : struct policy_handle unused_handle1, unused_handle2;
463 : char *server_name;
464 : uint32_t i;
465 0 : struct dcerpc_binding_handle *b = p->binding_handle;
466 :
467 0 : ctx = talloc_zero(tctx, struct test_spoolss_win_context);
468 0 : tmp_ctx = talloc_zero(tctx, struct test_spoolss_win_context);
469 :
470 0 : ret &= test_OpenPrinterSequence(tctx, p, &handle01);
471 0 : ret &= test_GetPrinterData(tctx, b, &handle01,"UISingleJobStatusString",
472 0 : WERR_INVALID_PARAMETER, 0);
473 0 : torture_comment(tctx, "Skip RemoteFindNextPrinterChangeNotifyEx test\n");
474 :
475 0 : server_name = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p));
476 0 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle1, server_name, 0);
477 :
478 0 : ret &= test_EnumPrinters(tctx, p, ctx, 1024);
479 :
480 0 : ret &= test_OpenPrinterEx(tctx, b, &handle02, server_name, 0);
481 0 : ret &= test_GetPrinterData(tctx, b, &handle02, "MajorVersion", WERR_OK,
482 : 3);
483 0 : ret &= test_ClosePrinter(tctx, b, &handle02);
484 :
485 : /* If no printers were found, skip all tests that need a printer */
486 0 : if (ctx->printer_count == 0) {
487 0 : goto end_testWinXP;
488 : }
489 :
490 0 : ret &= test_OpenPrinterEx(tctx, b, &handle02,
491 0 : ctx->printer_info[0].info2.printername,
492 : PRINTER_ACCESS_USE);
493 0 : ret &= test_GetPrinter(tctx, b, &handle02, ctx, 2, 0);
494 :
495 0 : 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 0 : ret &= test_OpenPrinterEx(tctx, b, &handle03,
501 0 : ctx->printer_info[0].info2.printername, 0);
502 0 : ret &= test_GetPrinter(tctx, b, &handle03, ctx, 0, 1164);
503 0 : ret &= test_GetPrinter(tctx, b, &handle03, ctx, 2, 0);
504 :
505 0 : ret &= test_OpenPrinterEx(tctx, b, &handle04,
506 0 : ctx->printer_info[0].info2.printername, 0);
507 0 : ret &= test_GetPrinter(tctx, b, &handle04, ctx, 2, 0);
508 0 : ret &= test_ClosePrinter(tctx, b, &handle04);
509 :
510 0 : ret &= test_OpenPrinterEx(tctx, b, &handle04,
511 0 : ctx->printer_info[0].info2.printername, 0);
512 0 : ret &= test_GetPrinter(tctx, b, &handle04, ctx, 2, 4096);
513 0 : ret &= test_ClosePrinter(tctx, b, &handle04);
514 :
515 0 : ret &= test_OpenPrinterAsAdmin(tctx, b,
516 0 : ctx->printer_info[0].info2.printername);
517 :
518 0 : ret &= test_OpenPrinterEx(tctx, b, &handle04,
519 0 : ctx->printer_info[0].info2.printername, PRINTER_READ);
520 0 : ret &= test_GetPrinterData(tctx, b, &handle04,"UISingleJobStatusString",
521 0 : WERR_FILE_NOT_FOUND, 0);
522 0 : torture_comment(tctx, "Skip RemoteFindNextPrinterChangeNotifyEx test\n");
523 :
524 0 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
525 0 : ctx->printer_info[0].info2.printername, 0);
526 :
527 0 : ret &= test_EnumJobs(tctx, b, &handle04);
528 0 : ret &= test_GetPrinter(tctx, b, &handle04, ctx, 2, 4096);
529 :
530 0 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
531 0 : ret &= test_ClosePrinter(tctx, b, &handle04);
532 :
533 0 : ret &= test_EnumPrinters(tctx, p, ctx, 1556);
534 0 : ret &= test_GetPrinterDriver2(tctx, b, ctx, &handle03);
535 0 : ret &= test_EnumForms(tctx, b, &handle03, 0);
536 :
537 0 : ret &= test_EnumPrinterKey(tctx, b, &handle03, "", ctx);
538 :
539 0 : for (i=0; ctx->printer_keys && ctx->printer_keys[i] != NULL; i++) {
540 :
541 0 : ret &= test_EnumPrinterKey(tctx, b, &handle03,
542 0 : ctx->printer_keys[i],
543 : tmp_ctx);
544 0 : ret &= test_EnumPrinterDataEx(tctx, b, &handle03,
545 0 : ctx->printer_keys[i], 0,
546 0 : WERR_OK);
547 : }
548 :
549 0 : ret &= test_EnumPrinterDataEx(tctx, b, &handle03, "", 0,
550 0 : WERR_INVALID_PARAMETER);
551 :
552 0 : ret &= test_GetPrinter(tctx, b, &handle03, tmp_ctx, 2, 0);
553 :
554 0 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
555 0 : ctx->printer_info[0].info2.printername, 0);
556 0 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
557 :
558 0 : ret &= test_GetPrinter(tctx, b, &handle03, tmp_ctx, 2, 2556);
559 :
560 0 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
561 0 : ctx->printer_info[0].info2.printername, 0);
562 0 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
563 :
564 0 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
565 0 : ctx->printer_info[0].info2.printername, 0);
566 0 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
567 :
568 0 : ret &= test_GetPrinter(tctx, b, &handle03, tmp_ctx, 7, 0);
569 :
570 0 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
571 0 : ctx->printer_info[0].info2.printername, 0);
572 0 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
573 :
574 0 : ret &= test_ClosePrinter(tctx, b, &handle03);
575 :
576 0 : ret &= test_OpenPrinterEx(tctx, b, &unused_handle2,
577 0 : ctx->printer_info[0].info2.printername, 0);
578 0 : ret &= test_ClosePrinter(tctx, b, &unused_handle2);
579 :
580 0 : ret &= test_OpenPrinterEx(tctx, b, &handle03, server_name, 0);
581 0 : ret &= test_GetPrinterData(tctx, b, &handle03, "W3SvcInstalled",
582 0 : WERR_OK, 0);
583 0 : ret &= test_ClosePrinter(tctx, b, &handle03);
584 :
585 0 : ret &= test_ClosePrinter(tctx, b, &unused_handle1);
586 0 : ret &= test_ClosePrinter(tctx, b, &handle02);
587 :
588 0 : ret &= test_OpenPrinterEx(tctx, b, &handle02,
589 0 : ctx->printer_info[0].info2.sharename, 0);
590 0 : ret &= test_GetPrinter(tctx, b, &handle02, tmp_ctx, 2, 0);
591 0 : ret &= test_ClosePrinter(tctx, b, &handle02);
592 :
593 0 : end_testWinXP:
594 0 : ret &= test_ClosePrinter(tctx, b, &handle01);
595 :
596 0 : talloc_free(tmp_ctx);
597 0 : talloc_free(ctx);
598 0 : return ret;
599 : }
600 :
601 964 : struct torture_suite *torture_rpc_spoolss_win(TALLOC_CTX *mem_ctx)
602 : {
603 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss.win");
604 :
605 964 : struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
606 : "win", &ndr_table_spoolss);
607 :
608 964 : torture_rpc_tcase_add_test(tcase, "testWinXP", test_WinXP);
609 :
610 964 : return suite;
611 : }
612 :
|