Finish removal of iconv_convenience in public API's.
[bbaumbach/samba-autobuild/.git] / source4 / torture / rap / printing.c
1 /*
2    Unix SMB/CIFS implementation.
3    test suite for SMB printing operations
4
5    Copyright (C) Guenther Deschner 2010
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 "libcli/raw/libcliraw.h"
23 #include "libcli/libcli.h"
24 #include "torture/torture.h"
25 #include "torture/util.h"
26 #include "system/filesys.h"
27
28 #include "torture/smbtorture.h"
29 #include "torture/util.h"
30 #include "../librpc/gen_ndr/rap.h"
31 #include "torture/rap/proto.h"
32 #include "param/param.h"
33
34
35 #define TORTURE_PRINT_FILE "torture_print_file"
36
37 static bool print_printjob(struct torture_context *tctx,
38                            struct smbcli_tree *tree)
39 {
40         int fnum;
41         DATA_BLOB data;
42         ssize_t size_written;
43         const char *str;
44
45         torture_comment(tctx, "creating printjob %s\n", TORTURE_PRINT_FILE);
46
47         fnum = smbcli_open(tree, TORTURE_PRINT_FILE, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
48         if (fnum == -1) {
49                 torture_fail(tctx, "failed to open file");
50         }
51
52         str = talloc_asprintf(tctx, "TortureTestPage: %d\nData\n",0);
53
54         data = data_blob_string_const(str);
55
56         size_written = smbcli_write(tree, fnum, 0, data.data, 0, data.length);
57         if (size_written != data.length) {
58                 torture_fail(tctx, "failed to write file");
59         }
60
61         torture_assert_ntstatus_ok(tctx,
62                 smbcli_close(tree, fnum),
63                 "failed to close file");
64
65         return true;
66 }
67
68 static bool test_raw_print(struct torture_context *tctx,
69                            struct smbcli_state *cli)
70 {
71         return print_printjob(tctx, cli->tree);
72 }
73
74 static bool test_netprintqenum(struct torture_context *tctx,
75                                struct smbcli_state *cli)
76 {
77         struct rap_NetPrintQEnum r;
78         int i, q;
79         uint16_t levels[] = { 0, 1, 2, 3, 4, 5 };
80
81         for (i=0; i < ARRAY_SIZE(levels); i++) {
82
83                 r.in.level = levels[i];
84                 r.in.bufsize = 8192;
85
86                 torture_comment(tctx,
87                         "Testing rap_NetPrintQEnum level %d\n", r.in.level);
88
89                 torture_assert_ntstatus_ok(tctx,
90                         smbcli_rap_netprintqenum(cli->tree, tctx, &r),
91                         "smbcli_rap_netprintqenum failed");
92                 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
93                         "failed to enum printq");
94
95                 for (q=0; q<r.out.count; q++) {
96                         switch (r.in.level) {
97                         case 0:
98                                 printf("%s\n", r.out.info[q].info0.PrintQName);
99                                 break;
100                         }
101                 }
102         }
103
104         return true;
105 }
106
107 static bool test_netprintqgetinfo(struct torture_context *tctx,
108                                   struct smbcli_state *cli)
109 {
110         struct rap_NetPrintQGetInfo r;
111         struct rap_NetPrintQEnum r_enum;
112         int i, p;
113         uint16_t levels[] = { 0, 1, 2, 3, 4, 5 };
114
115         r_enum.in.level = 5;
116         r_enum.in.bufsize = 8192;
117
118         torture_assert_ntstatus_ok(tctx,
119                 smbcli_rap_netprintqenum(cli->tree, tctx, &r_enum),
120                 "failed to enum printq");
121         torture_assert_werr_ok(tctx, W_ERROR(r_enum.out.status),
122                 "failed to enum printq");
123
124         for (p=0; p < r_enum.out.count; p++) {
125
126                 for (i=0; i < ARRAY_SIZE(levels); i++) {
127
128                         r.in.level = levels[i];
129                         r.in.bufsize = 8192;
130                         r.in.PrintQueueName = r_enum.out.info[p].info5.PrintQueueName;
131
132                         torture_comment(tctx, "Testing rap_NetPrintQGetInfo(%s) level %d\n",
133                                 r.in.PrintQueueName, r.in.level);
134
135                         torture_assert_ntstatus_ok(tctx,
136                                 smbcli_rap_netprintqgetinfo(cli->tree, tctx, &r),
137                                 "smbcli_rap_netprintqgetinfo failed");
138
139                         switch (r.in.level) {
140                         case 0:
141                                 printf("%s\n", r.out.info.info0.PrintQName);
142                                 break;
143                         }
144                 }
145         }
146
147         return true;
148 }
149
150 static bool test_netprintjob_pause(struct torture_context *tctx,
151                                    struct smbcli_state *cli,
152                                    uint16_t job_id)
153 {
154         struct rap_NetPrintJobPause r;
155
156         r.in.JobID = job_id;
157
158         torture_comment(tctx, "Testing rap_NetPrintJobPause(%d)\n", r.in.JobID);
159
160         torture_assert_ntstatus_ok(tctx,
161                 smbcli_rap_netprintjobpause(cli->tree, tctx, &r),
162                 "smbcli_rap_netprintjobpause failed");
163
164         return true;
165 }
166
167 static bool test_netprintjob_continue(struct torture_context *tctx,
168                                       struct smbcli_state *cli,
169                                       uint16_t job_id)
170 {
171         struct rap_NetPrintJobContinue r;
172
173         r.in.JobID = job_id;
174
175         torture_comment(tctx, "Testing rap_NetPrintJobContinue(%d)\n", r.in.JobID);
176
177         torture_assert_ntstatus_ok(tctx,
178                 smbcli_rap_netprintjobcontinue(cli->tree, tctx, &r),
179                 "smbcli_rap_netprintjobcontinue failed");
180
181         return true;
182 }
183
184 static bool test_netprintjob_delete(struct torture_context *tctx,
185                                     struct smbcli_state *cli,
186                                     uint16_t job_id)
187 {
188         struct rap_NetPrintJobDelete r;
189
190         r.in.JobID = job_id;
191
192         torture_comment(tctx, "Testing rap_NetPrintJobDelete(%d)\n", r.in.JobID);
193
194         torture_assert_ntstatus_ok(tctx,
195                 smbcli_rap_netprintjobdelete(cli->tree, tctx, &r),
196                 "smbcli_rap_netprintjobdelete failed");
197
198         return true;
199 }
200
201 static bool test_netprintjob(struct torture_context *tctx,
202                              struct smbcli_state *cli)
203 {
204         uint16_t job_id = 400;
205
206         torture_assert(tctx,
207                 test_netprintjob_pause(tctx, cli, job_id),
208                 "failed to pause job");
209         torture_assert(tctx,
210                 test_netprintjob_continue(tctx, cli, job_id),
211                 "failed to continue job");
212         torture_assert(tctx,
213                 test_netprintjob_delete(tctx, cli, job_id),
214                 "failed to delete job");
215
216         return true;
217 }
218
219 static bool test_netprintq_pause(struct torture_context *tctx,
220                                  struct smbcli_state *cli,
221                                  const char *PrintQueueName)
222 {
223         struct rap_NetPrintQueuePause r;
224
225         r.in.PrintQueueName = PrintQueueName;
226
227         torture_comment(tctx, "Testing rap_NetPrintQueuePause(%s)\n", r.in.PrintQueueName);
228
229         torture_assert_ntstatus_ok(tctx,
230                 smbcli_rap_netprintqueuepause(cli->tree, tctx, &r),
231                 "smbcli_rap_netprintqueuepause failed");
232         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
233                 "smbcli_rap_netprintqueuepause failed");
234
235         return true;
236 }
237
238 static bool test_netprintq_resume(struct torture_context *tctx,
239                                   struct smbcli_state *cli,
240                                   const char *PrintQueueName)
241 {
242         struct rap_NetPrintQueueResume r;
243
244         r.in.PrintQueueName = PrintQueueName;
245
246         torture_comment(tctx, "Testing rap_NetPrintQueueResume(%s)\n", r.in.PrintQueueName);
247
248         torture_assert_ntstatus_ok(tctx,
249                 smbcli_rap_netprintqueueresume(cli->tree, tctx, &r),
250                 "smbcli_rap_netprintqueueresume failed");
251         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
252                 "smbcli_rap_netprintqueueresume failed");
253
254         return true;
255 }
256
257 static bool test_netprintq(struct torture_context *tctx,
258                            struct smbcli_state *cli)
259 {
260         struct rap_NetPrintQEnum r;
261         int i;
262
263         r.in.level = 5;
264         r.in.bufsize = 8192;
265
266         torture_assert_ntstatus_ok(tctx,
267                 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
268                 "failed to enum printq");
269         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
270                 "failed to enum printq");
271
272         for (i=0; i < r.out.count; i++) {
273
274                 const char *printqname = r.out.info[i].info5.PrintQueueName;
275
276                 torture_assert(tctx,
277                         test_netprintq_pause(tctx, cli, printqname),
278                         "failed to pause print queue");
279
280                 torture_assert(tctx,
281                         test_netprintq_resume(tctx, cli, printqname),
282                         "failed to resume print queue");
283         }
284
285         return true;
286 }
287
288 static bool test_netprintjobenum_args(struct torture_context *tctx,
289                                       struct smbcli_state *cli,
290                                       const char *PrintQueueName,
291                                       uint16_t level,
292                                       uint16_t *count_p,
293                                       union rap_printj_info **info_p)
294 {
295         struct rap_NetPrintJobEnum r;
296
297         r.in.PrintQueueName = PrintQueueName;
298         r.in.bufsize = 8192;
299         r.in.level = level;
300
301         torture_comment(tctx,
302                 "Testing rap_NetPrintJobEnum(%s) level %d\n", r.in.PrintQueueName, r.in.level);
303
304         torture_assert_ntstatus_ok(tctx,
305                 smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
306                 "smbcli_rap_netprintjobenum failed");
307
308         if (count_p) {
309                 *count_p = r.out.count;
310         }
311         if (info_p) {
312                 *info_p = r.out.info;
313         }
314
315         return true;
316 }
317
318 static bool test_netprintjobenum_one(struct torture_context *tctx,
319                                      struct smbcli_state *cli,
320                                      const char *PrintQueueName)
321 {
322         struct rap_NetPrintJobEnum r;
323         int i;
324         uint16_t levels[] = { 0, 1, 2 };
325
326         r.in.PrintQueueName = PrintQueueName;
327         r.in.bufsize = 8192;
328
329         for (i=0; i < ARRAY_SIZE(levels); i++) {
330
331                 r.in.level = levels[i];
332
333                 torture_comment(tctx,
334                         "Testing rap_NetPrintJobEnum(%s) level %d\n", r.in.PrintQueueName, r.in.level);
335
336                 torture_assert_ntstatus_ok(tctx,
337                         smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
338                         "smbcli_rap_netprintjobenum failed");
339         }
340
341         return true;
342 }
343
344 static bool test_netprintjobgetinfo_byid(struct torture_context *tctx,
345                                          struct smbcli_state *cli,
346                                          uint16_t JobID)
347 {
348         struct rap_NetPrintJobGetInfo r;
349         uint16_t levels[] = { 0, 1, 2 };
350         int i;
351
352         r.in.JobID = JobID;
353         r.in.bufsize = 8192;
354
355         for (i=0; i < ARRAY_SIZE(levels); i++) {
356
357                 r.in.level = levels[i];
358
359                 torture_comment(tctx, "Testing rap_NetPrintJobGetInfo(%d) level %d\n", r.in.JobID, r.in.level);
360
361                 torture_assert_ntstatus_ok(tctx,
362                         smbcli_rap_netprintjobgetinfo(cli->tree, tctx, &r),
363                         "smbcli_rap_netprintjobgetinfo failed");
364         }
365
366         return true;
367 }
368
369 static bool test_netprintjobsetinfo_byid(struct torture_context *tctx,
370                                          struct smbcli_state *cli,
371                                          uint16_t JobID)
372 {
373         struct rap_NetPrintJobSetInfo r;
374         uint16_t levels[] = { 0, 1, 2 };
375         int i;
376         const char *comment = "tortured by samba";
377
378         r.in.JobID = JobID;
379         r.in.bufsize = strlen(comment);
380         r.in.ParamNum = RAP_PARAM_JOBCOMMENT;
381         r.in.Param.string = comment;
382
383         for (i=0; i < ARRAY_SIZE(levels); i++) {
384
385                 r.in.level = levels[i];
386
387                 torture_comment(tctx, "Testing rap_NetPrintJobSetInfo(%d) level %d\n", r.in.JobID, r.in.level);
388
389                 torture_assert_ntstatus_ok(tctx,
390                         smbcli_rap_netprintjobsetinfo(cli->tree, tctx, &r),
391                         "smbcli_rap_netprintjobsetinfo failed");
392         }
393
394         return true;
395 }
396
397
398 static bool test_netprintjobgetinfo_byqueue(struct torture_context *tctx,
399                                             struct smbcli_state *cli,
400                                             const char *PrintQueueName)
401 {
402         struct rap_NetPrintJobEnum r;
403         int i;
404
405         r.in.PrintQueueName = PrintQueueName;
406         r.in.bufsize = 8192;
407         r.in.level = 0;
408
409         torture_assert_ntstatus_ok(tctx,
410                 smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
411                 "failed to enumerate jobs");
412
413         for (i=0; i < r.out.count; i++) {
414
415                 torture_assert(tctx,
416                         test_netprintjobgetinfo_byid(tctx, cli, r.out.info[i].info0.JobID),
417                         "failed to get job info");
418         }
419
420         return true;
421 }
422
423 static bool test_netprintjobsetinfo_byqueue(struct torture_context *tctx,
424                                             struct smbcli_state *cli,
425                                             const char *PrintQueueName)
426 {
427         struct rap_NetPrintJobEnum r;
428         int i;
429
430         r.in.PrintQueueName = PrintQueueName;
431         r.in.bufsize = 8192;
432         r.in.level = 0;
433
434         torture_assert_ntstatus_ok(tctx,
435                 smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
436                 "failed to enumerate jobs");
437
438         for (i=0; i < r.out.count; i++) {
439
440                 torture_assert(tctx,
441                         test_netprintjobsetinfo_byid(tctx, cli, r.out.info[i].info0.JobID),
442                         "failed to set job info");
443         }
444
445         return true;
446 }
447
448 static bool test_netprintjobenum(struct torture_context *tctx,
449                                  struct smbcli_state *cli)
450 {
451         struct rap_NetPrintQEnum r;
452         int i;
453
454         r.in.level = 5;
455         r.in.bufsize = 8192;
456
457         torture_assert_ntstatus_ok(tctx,
458                 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
459                 "failed to enum printq");
460         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
461                 "failed to enum printq");
462
463         for (i=0; i < r.out.count; i++) {
464
465                 const char *printqname = r.out.info[i].info5.PrintQueueName;
466
467                 torture_assert(tctx,
468                         test_netprintjobenum_one(tctx, cli, printqname),
469                         "failed to enumerate printjobs on print queue");
470         }
471
472         return true;
473 }
474
475 static bool test_netprintjobgetinfo(struct torture_context *tctx,
476                                     struct smbcli_state *cli)
477 {
478         struct rap_NetPrintQEnum r;
479         int i;
480
481         r.in.level = 5;
482         r.in.bufsize = 8192;
483
484         torture_assert_ntstatus_ok(tctx,
485                 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
486                 "failed to enum printq");
487         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
488                 "failed to enum printq");
489
490         for (i=0; i < r.out.count; i++) {
491
492                 const char *printqname = r.out.info[i].info5.PrintQueueName;
493
494                 torture_assert(tctx,
495                         test_netprintjobgetinfo_byqueue(tctx, cli, printqname),
496                         "failed to enumerate printjobs on print queue");
497         }
498
499         return true;
500 }
501
502 static bool test_netprintjobsetinfo(struct torture_context *tctx,
503                                     struct smbcli_state *cli)
504 {
505         struct rap_NetPrintQEnum r;
506         int i;
507
508         r.in.level = 5;
509         r.in.bufsize = 8192;
510
511         torture_assert_ntstatus_ok(tctx,
512                 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
513                 "failed to enum printq");
514         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
515                 "failed to enum printq");
516
517         for (i=0; i < r.out.count; i++) {
518
519                 const char *printqname = r.out.info[i].info5.PrintQueueName;
520
521                 torture_assert(tctx,
522                         test_netprintjobsetinfo_byqueue(tctx, cli, printqname),
523                         "failed to set printjobs on print queue");
524         }
525
526         return true;
527 }
528
529 static bool test_netprintdestenum(struct torture_context *tctx,
530                                   struct smbcli_state *cli)
531 {
532         struct rap_NetPrintDestEnum r;
533         int i;
534         uint16_t levels[] = { 0, 1, 2, 3 };
535
536         for (i=0; i < ARRAY_SIZE(levels); i++) {
537
538                 r.in.level = levels[i];
539                 r.in.bufsize = 8192;
540
541                 torture_comment(tctx,
542                         "Testing rap_NetPrintDestEnum level %d\n", r.in.level);
543
544                 torture_assert_ntstatus_ok(tctx,
545                         smbcli_rap_netprintdestenum(cli->tree, tctx, &r),
546                         "smbcli_rap_netprintdestenum failed");
547         }
548
549         return true;
550 }
551
552 static bool test_netprintdestgetinfo_bydest(struct torture_context *tctx,
553                                             struct smbcli_state *cli,
554                                             const char *PrintDestName)
555 {
556         struct rap_NetPrintDestGetInfo r;
557         int i;
558         uint16_t levels[] = { 0, 1, 2, 3 };
559
560         for (i=0; i < ARRAY_SIZE(levels); i++) {
561
562                 r.in.PrintDestName = PrintDestName;
563                 r.in.level = levels[i];
564                 r.in.bufsize = 8192;
565
566                 torture_comment(tctx,
567                         "Testing rap_NetPrintDestGetInfo(%s) level %d\n", r.in.PrintDestName, r.in.level);
568
569                 torture_assert_ntstatus_ok(tctx,
570                         smbcli_rap_netprintdestgetinfo(cli->tree, tctx, &r),
571                         "smbcli_rap_netprintdestgetinfo failed");
572         }
573
574         return true;
575 }
576
577
578 static bool test_netprintdestgetinfo(struct torture_context *tctx,
579                                      struct smbcli_state *cli)
580 {
581         struct rap_NetPrintDestEnum r;
582         int i;
583
584         r.in.level = 2;
585         r.in.bufsize = 8192;
586
587         torture_comment(tctx,
588                 "Testing rap_NetPrintDestEnum level %d\n", r.in.level);
589
590         torture_assert_ntstatus_ok(tctx,
591                 smbcli_rap_netprintdestenum(cli->tree, tctx, &r),
592                 "smbcli_rap_netprintdestenum failed");
593
594         for (i=0; i < r.out.count; i++) {
595
596                 torture_assert(tctx,
597                         test_netprintdestgetinfo_bydest(tctx, cli, r.out.info[i].info2.PrinterName),
598                         "failed to get printdest info");
599
600         }
601
602         return true;
603 }
604
605 static bool test_rap_print(struct torture_context *tctx,
606                            struct smbcli_state *cli)
607 {
608         struct rap_NetPrintQEnum r;
609         int i;
610
611         r.in.level = 5;
612         r.in.bufsize = 8192;
613
614         torture_assert_ntstatus_ok(tctx,
615                 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
616                 "failed to enum printq");
617         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
618                 "failed to enum printq");
619
620         for (i=0; i < r.out.count; i++) {
621
622                 const char *printqname = r.out.info[i].info5.PrintQueueName;
623                 struct smbcli_tree *res_queue = NULL;
624                 uint16_t num_jobs;
625                 union rap_printj_info *job_info;
626                 int j;
627
628                 torture_assert(tctx,
629                         test_netprintq_pause(tctx, cli, printqname),
630                         "failed to set printjobs on print queue");
631
632                 torture_assert_ntstatus_ok(tctx,
633                         torture_second_tcon(tctx, cli->session, printqname, &res_queue),
634                         "failed to open 2nd connection");
635
636                 torture_assert(tctx,
637                         print_printjob(tctx, res_queue),
638                         "failed to print job on 2nd connection");
639
640                 talloc_free(res_queue);
641
642                 torture_assert(tctx,
643                         test_netprintjobenum_args(tctx, cli, printqname, 1,
644                         &num_jobs, &job_info),
645                         "failed to enum printjobs on print queue");
646
647                 for (j=0; j < num_jobs; j++) {
648
649                         uint16_t job_id = job_info[j].info1.JobID;
650
651                         torture_assert(tctx,
652                                 test_netprintjobgetinfo_byid(tctx, cli, job_id),
653                                 "failed to getinfo on new printjob");
654
655                         torture_assert(tctx,
656                                 test_netprintjob_delete(tctx, cli, job_id),
657                                 "failed to delete job");
658                 }
659
660                 torture_assert(tctx,
661                         test_netprintq_resume(tctx, cli, printqname),
662                         "failed to resume print queue");
663
664         }
665
666         return true;
667 }
668
669 struct torture_suite *torture_rap_printing(TALLOC_CTX *mem_ctx)
670 {
671         struct torture_suite *suite = torture_suite_create(mem_ctx, "PRINTING");
672
673         torture_suite_add_1smb_test(suite, "raw_print", test_raw_print);
674         torture_suite_add_1smb_test(suite, "rap_print", test_rap_print);
675         torture_suite_add_1smb_test(suite, "rap_printq_enum", test_netprintqenum);
676         torture_suite_add_1smb_test(suite, "rap_printq_getinfo", test_netprintqgetinfo);
677         torture_suite_add_1smb_test(suite, "rap_printq", test_netprintq);
678         torture_suite_add_1smb_test(suite, "rap_printjob_enum", test_netprintjobenum);
679         torture_suite_add_1smb_test(suite, "rap_printjob_getinfo", test_netprintjobgetinfo);
680         torture_suite_add_1smb_test(suite, "rap_printjob_setinfo", test_netprintjobsetinfo);
681         torture_suite_add_1smb_test(suite, "rap_printjob", test_netprintjob);
682         torture_suite_add_1smb_test(suite, "rap_printdest_enum", test_netprintdestenum);
683         torture_suite_add_1smb_test(suite, "rap_printdest_getinfo", test_netprintdestgetinfo);
684
685         return suite;
686 }