~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/rpc/spoolss_win.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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