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