call OpenPrinterEx on each printer on the server, and then call
[kai/samba.git] / source4 / torture / rpc / spoolss.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for spoolss rpc operations
4
5    Copyright (C) Tim Potter 2003
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 2 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, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
25                      struct policy_handle *handle)
26 {
27         NTSTATUS status;
28         struct spoolss_GetPrinter r;
29         uint32 buf_size = 0;
30         DATA_BLOB blob;
31         union spoolss_PrinterInfo info;
32         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7};
33         int i;
34         BOOL ret = True;
35         
36         for (i=0;i<ARRAY_SIZE(levels);i++) {
37                 r.in.handle = handle;
38                 r.in.level = levels[i];
39                 r.in.buffer = NULL;
40                 r.in.buf_size = &buf_size;
41                 r.out.buf_size = &buf_size;
42
43                 printf("Testing GetPrinter level %u\n", r.in.level);
44
45                 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
46                 if (!NT_STATUS_IS_OK(status)) {
47                         printf("GetPrinter failed - %s\n", nt_errstr(status));
48                         ret = False;
49                         continue;
50                 }
51                 
52                 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
53                         blob = data_blob_talloc(mem_ctx, NULL, buf_size);
54                         data_blob_clear(&blob);
55                         r.in.buffer = &blob;
56                         status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
57                 }
58                 
59                 if (!NT_STATUS_IS_OK(status) ||
60                     !W_ERROR_IS_OK(r.out.result)) {
61                         printf("GetPrinter failed - %s/%s\n", 
62                                nt_errstr(status), win_errstr(r.out.result));
63                         ret = False;
64                         continue;
65                 }
66                 
67                 status = ndr_pull_union_blob(r.out.buffer, mem_ctx, r.in.level, &info,
68                                              (ndr_pull_union_fn_t)ndr_pull_spoolss_PrinterInfo);
69                 if (!NT_STATUS_IS_OK(status)) {
70                         printf("PrinterInfo parse failed - %s\n", nt_errstr(status));
71                         ret = False;
72                         continue;
73                 }
74                 
75                 NDR_PRINT_UNION_DEBUG(spoolss_PrinterInfo, r.in.level, &info);
76         }
77
78         return ret;
79 }
80
81
82 BOOL test_ClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
83                        struct policy_handle *handle)
84 {
85         NTSTATUS status;
86         struct spoolss_ClosePrinter r;
87
88         r.in.handle = handle;
89         r.out.handle = handle;
90
91         printf("Testing ClosePrinter\n");
92
93         status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
94         if (!NT_STATUS_IS_OK(status)) {
95                 printf("ClosePrinter failed - %s\n", nt_errstr(status));
96                 return False;
97         }
98
99         return True;
100 }
101
102 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
103                              const char *name)
104 {
105         NTSTATUS status;
106         struct spoolss_OpenPrinter r;
107         struct policy_handle handle;
108         DATA_BLOB blob;
109         BOOL ret = True;
110
111         blob = data_blob(NULL, 0);
112
113         r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
114         r.in.printer = name;
115         r.in.buffer = &blob;
116         r.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;  
117         r.out.handle = &handle;
118
119         printf("\nTesting OpenPrinter(\\\\%s\\%s)\n", r.in.server, r.in.printer);
120
121         status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
122         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
123                 printf("OpenPrinter failed - %s/%s\n", 
124                        nt_errstr(status), win_errstr(r.out.result));
125                 return False;
126         }
127
128
129         if (!test_GetPrinter(p, mem_ctx, &handle)) {
130                 ret = False;
131         }
132
133         if (!test_ClosePrinter(p, mem_ctx, &handle)) {
134                 ret = False;
135         }
136         
137         return ret;
138 }
139
140 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
141                                const char *name)
142 {
143         struct policy_handle handle;
144         struct spoolss_OpenPrinterEx r;
145         struct spoolss_UserLevel1 userlevel1;
146         NTSTATUS status;
147         BOOL ret = True;
148
149         r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", 
150                                            dcerpc_server_name(p), name);
151         r.in.datatype = NULL;
152         r.in.devmode_ctr.size = 0;
153         r.in.devmode_ctr.devmode = NULL;
154         r.in.access_required = 0x02000000;
155         r.in.level = 1;
156         r.out.handle = &handle;
157
158         userlevel1.size = 1234;
159         userlevel1.client = "hello";
160         userlevel1.user = "spottyfoot!";
161         userlevel1.build = 1;
162         userlevel1.major = 2;
163         userlevel1.minor = 3;
164         userlevel1.processor = 4;
165         r.in.userlevel.level1 = &userlevel1;
166
167         printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
168
169         status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
170
171         if (!NT_STATUS_IS_OK(status)) {
172                 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
173                 return False;
174         }
175
176         if (!W_ERROR_IS_OK(r.out.result)) {
177                 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
178                 return False;
179         }
180
181         if (!test_GetPrinter(p, mem_ctx, &handle)) {
182                 ret = False;
183         }
184
185         if (!test_ClosePrinter(p, mem_ctx, &handle)) {
186                 ret = False;
187         }
188
189         return ret;
190 }
191
192
193 static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
194 {
195         struct spoolss_EnumPrinters r;
196         NTSTATUS status;
197         uint16 levels[] = {1, 2, 3, 4, 5, 6, 7};
198         int i;
199         BOOL ret = True;
200
201         for (i=0;i<ARRAY_SIZE(levels);i++) {
202                 uint32 buf_size = 0;
203                 union spoolss_PrinterInfo *info;
204                 int j;
205
206                 r.in.flags = 0x02;
207                 r.in.server = "";
208                 r.in.level = levels[i];
209                 r.in.buffer = NULL;
210                 r.in.buf_size = &buf_size;
211                 r.out.buf_size = &buf_size;
212
213                 printf("\nTesting EnumPrinters level %u\n", r.in.level);
214
215                 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
216                 if (!NT_STATUS_IS_OK(status)) {
217                         printf("EnumPrinters failed - %s\n", nt_errstr(status));
218                         ret = False;
219                         continue;
220                 }
221                 
222                 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
223                         DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
224                         data_blob_clear(&blob);
225                         r.in.buffer = &blob;
226                         status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
227                 }
228                 
229                 if (!NT_STATUS_IS_OK(status) ||
230                     !W_ERROR_IS_OK(r.out.result)) {
231                         printf("EnumPrinters failed - %s/%s\n", 
232                                nt_errstr(status), win_errstr(r.out.result));
233                         continue;
234                 }
235
236                 status = pull_spoolss_PrinterInfoArray(r.out.buffer, mem_ctx, r.in.level, r.out.count, &info);
237                 if (!NT_STATUS_IS_OK(status)) {
238                         printf("EnumPrintersArray parse failed - %s\n", nt_errstr(status));
239                         continue;
240                 }
241
242                 for (j=0;j<r.out.count;j++) {
243                         printf("Printer %d\n", j);
244                         NDR_PRINT_UNION_DEBUG(spoolss_PrinterInfo, r.in.level, &info[j]);
245                 }
246
247                 for (j=0;j<r.out.count;j++) {
248                         if (r.in.level == 1) {
249                                 /* the names appear to be comma-separated name lists? */
250                                 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
251                                 char *comma = strchr(name, ',');
252                                 if (comma) *comma = 0;
253                                 if (!test_OpenPrinter(p, mem_ctx, name)) {
254                                         ret = False;
255                                 }
256
257                                 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
258                                         ret = False;
259                                 }
260                         }
261                 }
262         }
263         
264         return ret;
265 }
266
267 BOOL torture_rpc_spoolss(int dummy)
268 {
269         NTSTATUS status;
270         struct dcerpc_pipe *p;
271         TALLOC_CTX *mem_ctx;
272         BOOL ret = True;
273
274         mem_ctx = talloc_init("torture_rpc_spoolss");
275
276         status = torture_rpc_connection(&p, "spoolss");
277         if (!NT_STATUS_IS_OK(status)) {
278                 return False;
279         }
280         
281         if (!test_EnumPrinters(p, mem_ctx)) {
282                 ret = False;
283         }
284
285         torture_rpc_close(p);
286
287         return ret;
288 }