/src/samba/source3/rpc_client/cli_spoolss.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Unix SMB/CIFS implementation. |
3 | | RPC pipe client |
4 | | |
5 | | Copyright (C) Gerald Carter 2001-2005, |
6 | | Copyright (C) Tim Potter 2000-2002, |
7 | | Copyright (C) Andrew Tridgell 1994-2000, |
8 | | Copyright (C) Jean-Francois Micouleau 1999-2000. |
9 | | Copyright (C) Jeremy Allison 2005. |
10 | | |
11 | | This program is free software; you can redistribute it and/or modify |
12 | | it under the terms of the GNU General Public License as published by |
13 | | the Free Software Foundation; either version 3 of the License, or |
14 | | (at your option) any later version. |
15 | | |
16 | | This program is distributed in the hope that it will be useful, |
17 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | | GNU General Public License for more details. |
20 | | |
21 | | You should have received a copy of the GNU General Public License |
22 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
23 | | */ |
24 | | |
25 | | #include "includes.h" |
26 | | #include "rpc_client/rpc_client.h" |
27 | | #include "../librpc/gen_ndr/ndr_spoolss_c.h" |
28 | | #include "rpc_client/cli_spoolss.h" |
29 | | #include "auth/gensec/gensec.h" |
30 | | #include "auth/credentials/credentials.h" |
31 | | #include "rpc_client/init_spoolss.h" |
32 | | |
33 | | /********************************************************************** |
34 | | convenience wrapper around rpccli_spoolss_OpenPrinterEx |
35 | | **********************************************************************/ |
36 | | |
37 | | WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli, |
38 | | TALLOC_CTX *mem_ctx, |
39 | | const char *printername, |
40 | | uint32_t access_desired, |
41 | | struct policy_handle *handle) |
42 | 0 | { |
43 | 0 | NTSTATUS status; |
44 | 0 | WERROR werror; |
45 | 0 | struct spoolss_DevmodeContainer devmode_ctr; |
46 | 0 | struct spoolss_UserLevelCtr userlevel_ctr; |
47 | 0 | struct spoolss_UserLevel1 level1; |
48 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
49 | |
|
50 | 0 | ZERO_STRUCT(devmode_ctr); |
51 | |
|
52 | 0 | werror = spoolss_init_spoolss_UserLevel1(mem_ctx, |
53 | 0 | cli->printer_username, |
54 | 0 | &level1); |
55 | 0 | if (!W_ERROR_IS_OK(werror)) { |
56 | 0 | return werror; |
57 | 0 | } |
58 | | |
59 | 0 | userlevel_ctr.level = 1; |
60 | 0 | userlevel_ctr.user_info.level1 = &level1; |
61 | |
|
62 | 0 | status = dcerpc_spoolss_OpenPrinterEx(b, mem_ctx, |
63 | 0 | printername, |
64 | 0 | NULL, |
65 | 0 | devmode_ctr, |
66 | 0 | access_desired, |
67 | 0 | userlevel_ctr, |
68 | 0 | handle, |
69 | 0 | &werror); |
70 | |
|
71 | 0 | if (!NT_STATUS_IS_OK(status)) { |
72 | 0 | return ntstatus_to_werror(status); |
73 | 0 | } |
74 | | |
75 | 0 | if (!W_ERROR_IS_OK(werror)) { |
76 | 0 | return werror; |
77 | 0 | } |
78 | | |
79 | 0 | return WERR_OK; |
80 | 0 | } |
81 | | |
82 | | /********************************************************************** |
83 | | convenience wrapper around rpccli_spoolss_GetPrinterDriver |
84 | | **********************************************************************/ |
85 | | |
86 | | WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, |
87 | | TALLOC_CTX *mem_ctx, |
88 | | struct policy_handle *handle, |
89 | | const char *architecture, |
90 | | uint32_t level, |
91 | | uint32_t offered, |
92 | | union spoolss_DriverInfo *info) |
93 | 0 | { |
94 | 0 | NTSTATUS status; |
95 | 0 | WERROR werror; |
96 | 0 | uint32_t needed; |
97 | 0 | DATA_BLOB buffer; |
98 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
99 | |
|
100 | 0 | if (offered > 0) { |
101 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
102 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
103 | 0 | } |
104 | | |
105 | 0 | status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx, |
106 | 0 | handle, |
107 | 0 | architecture, |
108 | 0 | level, |
109 | 0 | (offered > 0) ? &buffer : NULL, |
110 | 0 | offered, |
111 | 0 | info, |
112 | 0 | &needed, |
113 | 0 | &werror); |
114 | 0 | if (!NT_STATUS_IS_OK(status)) { |
115 | 0 | return ntstatus_to_werror(status); |
116 | 0 | } |
117 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
118 | 0 | offered = needed; |
119 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
120 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
121 | | |
122 | 0 | status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx, |
123 | 0 | handle, |
124 | 0 | architecture, |
125 | 0 | level, |
126 | 0 | &buffer, |
127 | 0 | offered, |
128 | 0 | info, |
129 | 0 | &needed, |
130 | 0 | &werror); |
131 | 0 | } |
132 | 0 | if (!NT_STATUS_IS_OK(status)) { |
133 | 0 | return ntstatus_to_werror(status); |
134 | 0 | } |
135 | | |
136 | 0 | return werror; |
137 | 0 | } |
138 | | |
139 | | /********************************************************************** |
140 | | convenience wrapper around rpccli_spoolss_GetPrinterDriver2 |
141 | | **********************************************************************/ |
142 | | |
143 | | WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, |
144 | | TALLOC_CTX *mem_ctx, |
145 | | struct policy_handle *handle, |
146 | | const char *architecture, |
147 | | uint32_t level, |
148 | | uint32_t offered, |
149 | | uint32_t client_major_version, |
150 | | uint32_t client_minor_version, |
151 | | union spoolss_DriverInfo *info, |
152 | | uint32_t *server_major_version, |
153 | | uint32_t *server_minor_version) |
154 | 0 | { |
155 | 0 | NTSTATUS status; |
156 | 0 | WERROR werror; |
157 | 0 | uint32_t needed; |
158 | 0 | DATA_BLOB buffer; |
159 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
160 | |
|
161 | 0 | if (offered > 0) { |
162 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
163 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
164 | 0 | } |
165 | | |
166 | 0 | status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx, |
167 | 0 | handle, |
168 | 0 | architecture, |
169 | 0 | level, |
170 | 0 | (offered > 0) ? &buffer : NULL, |
171 | 0 | offered, |
172 | 0 | client_major_version, |
173 | 0 | client_minor_version, |
174 | 0 | info, |
175 | 0 | &needed, |
176 | 0 | server_major_version, |
177 | 0 | server_minor_version, |
178 | 0 | &werror); |
179 | 0 | if (!NT_STATUS_IS_OK(status)) { |
180 | 0 | return ntstatus_to_werror(status); |
181 | 0 | } |
182 | | |
183 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
184 | 0 | offered = needed; |
185 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
186 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
187 | | |
188 | 0 | status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx, |
189 | 0 | handle, |
190 | 0 | architecture, |
191 | 0 | level, |
192 | 0 | &buffer, |
193 | 0 | offered, |
194 | 0 | client_major_version, |
195 | 0 | client_minor_version, |
196 | 0 | info, |
197 | 0 | &needed, |
198 | 0 | server_major_version, |
199 | 0 | server_minor_version, |
200 | 0 | &werror); |
201 | 0 | } |
202 | 0 | if (!NT_STATUS_IS_OK(status)) { |
203 | 0 | return ntstatus_to_werror(status); |
204 | 0 | } |
205 | | |
206 | 0 | return werror; |
207 | 0 | } |
208 | | |
209 | | /********************************************************************** |
210 | | convenience wrapper around rpccli_spoolss_AddPrinterEx |
211 | | **********************************************************************/ |
212 | | |
213 | | WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, |
214 | | TALLOC_CTX *mem_ctx, |
215 | | struct spoolss_SetPrinterInfoCtr *info_ctr) |
216 | 0 | { |
217 | 0 | WERROR result; |
218 | 0 | NTSTATUS status; |
219 | 0 | struct spoolss_DevmodeContainer devmode_ctr; |
220 | 0 | struct sec_desc_buf secdesc_ctr; |
221 | 0 | struct spoolss_UserLevelCtr userlevel_ctr; |
222 | 0 | struct spoolss_UserLevel1 level1; |
223 | 0 | struct policy_handle handle; |
224 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
225 | |
|
226 | 0 | ZERO_STRUCT(devmode_ctr); |
227 | 0 | ZERO_STRUCT(secdesc_ctr); |
228 | |
|
229 | 0 | result = spoolss_init_spoolss_UserLevel1(mem_ctx, |
230 | 0 | cli->printer_username, |
231 | 0 | &level1); |
232 | 0 | if (!W_ERROR_IS_OK(result)) { |
233 | 0 | return result; |
234 | 0 | } |
235 | | |
236 | 0 | userlevel_ctr.level = 1; |
237 | 0 | userlevel_ctr.user_info.level1 = &level1; |
238 | |
|
239 | 0 | status = dcerpc_spoolss_AddPrinterEx(b, mem_ctx, |
240 | 0 | cli->srv_name_slash, |
241 | 0 | info_ctr, |
242 | 0 | &devmode_ctr, |
243 | 0 | &secdesc_ctr, |
244 | 0 | &userlevel_ctr, |
245 | 0 | &handle, |
246 | 0 | &result); |
247 | 0 | if (!NT_STATUS_IS_OK(status)) { |
248 | 0 | return ntstatus_to_werror(status); |
249 | 0 | } |
250 | | |
251 | 0 | return result; |
252 | 0 | } |
253 | | |
254 | | /********************************************************************** |
255 | | convenience wrapper around rpccli_spoolss_GetPrinter |
256 | | **********************************************************************/ |
257 | | |
258 | | WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, |
259 | | TALLOC_CTX *mem_ctx, |
260 | | struct policy_handle *handle, |
261 | | uint32_t level, |
262 | | uint32_t offered, |
263 | | union spoolss_PrinterInfo *info) |
264 | 0 | { |
265 | 0 | NTSTATUS status; |
266 | 0 | WERROR werror; |
267 | 0 | DATA_BLOB buffer; |
268 | 0 | uint32_t needed; |
269 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
270 | |
|
271 | 0 | if (offered > 0) { |
272 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
273 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
274 | 0 | } |
275 | | |
276 | 0 | status = dcerpc_spoolss_GetPrinter(b, mem_ctx, |
277 | 0 | handle, |
278 | 0 | level, |
279 | 0 | (offered > 0) ? &buffer : NULL, |
280 | 0 | offered, |
281 | 0 | info, |
282 | 0 | &needed, |
283 | 0 | &werror); |
284 | 0 | if (!NT_STATUS_IS_OK(status)) { |
285 | 0 | return ntstatus_to_werror(status); |
286 | 0 | } |
287 | | |
288 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
289 | |
|
290 | 0 | offered = needed; |
291 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
292 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
293 | | |
294 | 0 | status = dcerpc_spoolss_GetPrinter(b, mem_ctx, |
295 | 0 | handle, |
296 | 0 | level, |
297 | 0 | &buffer, |
298 | 0 | offered, |
299 | 0 | info, |
300 | 0 | &needed, |
301 | 0 | &werror); |
302 | 0 | } |
303 | 0 | if (!NT_STATUS_IS_OK(status)) { |
304 | 0 | return ntstatus_to_werror(status); |
305 | 0 | } |
306 | | |
307 | 0 | return werror; |
308 | 0 | } |
309 | | |
310 | | /********************************************************************** |
311 | | convenience wrapper around rpccli_spoolss_GetJob |
312 | | **********************************************************************/ |
313 | | |
314 | | WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, |
315 | | TALLOC_CTX *mem_ctx, |
316 | | struct policy_handle *handle, |
317 | | uint32_t job_id, |
318 | | uint32_t level, |
319 | | uint32_t offered, |
320 | | union spoolss_JobInfo *info) |
321 | 0 | { |
322 | 0 | NTSTATUS status; |
323 | 0 | WERROR werror; |
324 | 0 | uint32_t needed; |
325 | 0 | DATA_BLOB buffer; |
326 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
327 | |
|
328 | 0 | if (offered > 0) { |
329 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
330 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
331 | 0 | } |
332 | | |
333 | 0 | status = dcerpc_spoolss_GetJob(b, mem_ctx, |
334 | 0 | handle, |
335 | 0 | job_id, |
336 | 0 | level, |
337 | 0 | (offered > 0) ? &buffer : NULL, |
338 | 0 | offered, |
339 | 0 | info, |
340 | 0 | &needed, |
341 | 0 | &werror); |
342 | 0 | if (!NT_STATUS_IS_OK(status)) { |
343 | 0 | return ntstatus_to_werror(status); |
344 | 0 | } |
345 | | |
346 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
347 | 0 | offered = needed; |
348 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
349 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
350 | | |
351 | 0 | status = dcerpc_spoolss_GetJob(b, mem_ctx, |
352 | 0 | handle, |
353 | 0 | job_id, |
354 | 0 | level, |
355 | 0 | &buffer, |
356 | 0 | offered, |
357 | 0 | info, |
358 | 0 | &needed, |
359 | 0 | &werror); |
360 | 0 | } |
361 | 0 | if (!NT_STATUS_IS_OK(status)) { |
362 | 0 | return ntstatus_to_werror(status); |
363 | 0 | } |
364 | | |
365 | 0 | return werror; |
366 | 0 | } |
367 | | |
368 | | /********************************************************************** |
369 | | convenience wrapper around rpccli_spoolss_EnumForms |
370 | | **********************************************************************/ |
371 | | |
372 | | WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, |
373 | | TALLOC_CTX *mem_ctx, |
374 | | struct policy_handle *handle, |
375 | | uint32_t level, |
376 | | uint32_t offered, |
377 | | uint32_t *count, |
378 | | union spoolss_FormInfo **info) |
379 | 0 | { |
380 | 0 | NTSTATUS status; |
381 | 0 | WERROR werror; |
382 | 0 | uint32_t needed; |
383 | 0 | DATA_BLOB buffer; |
384 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
385 | |
|
386 | 0 | if (offered > 0) { |
387 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
388 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
389 | 0 | } |
390 | | |
391 | 0 | status = dcerpc_spoolss_EnumForms(b, mem_ctx, |
392 | 0 | handle, |
393 | 0 | level, |
394 | 0 | (offered > 0) ? &buffer : NULL, |
395 | 0 | offered, |
396 | 0 | count, |
397 | 0 | info, |
398 | 0 | &needed, |
399 | 0 | &werror); |
400 | 0 | if (!NT_STATUS_IS_OK(status)) { |
401 | 0 | return ntstatus_to_werror(status); |
402 | 0 | } |
403 | | |
404 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
405 | 0 | offered = needed; |
406 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
407 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
408 | | |
409 | 0 | status = dcerpc_spoolss_EnumForms(b, mem_ctx, |
410 | 0 | handle, |
411 | 0 | level, |
412 | 0 | (offered > 0) ? &buffer : NULL, |
413 | 0 | offered, |
414 | 0 | count, |
415 | 0 | info, |
416 | 0 | &needed, |
417 | 0 | &werror); |
418 | 0 | } |
419 | 0 | if (!NT_STATUS_IS_OK(status)) { |
420 | 0 | return ntstatus_to_werror(status); |
421 | 0 | } |
422 | | |
423 | 0 | return werror; |
424 | 0 | } |
425 | | |
426 | | /********************************************************************** |
427 | | convenience wrapper around rpccli_spoolss_EnumPrintProcessors |
428 | | **********************************************************************/ |
429 | | |
430 | | WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli, |
431 | | TALLOC_CTX *mem_ctx, |
432 | | const char *servername, |
433 | | const char *environment, |
434 | | uint32_t level, |
435 | | uint32_t offered, |
436 | | uint32_t *count, |
437 | | union spoolss_PrintProcessorInfo **info) |
438 | 0 | { |
439 | 0 | NTSTATUS status; |
440 | 0 | WERROR werror; |
441 | 0 | uint32_t needed; |
442 | 0 | DATA_BLOB buffer; |
443 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
444 | |
|
445 | 0 | if (offered > 0) { |
446 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
447 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
448 | 0 | } |
449 | | |
450 | 0 | status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx, |
451 | 0 | servername, |
452 | 0 | environment, |
453 | 0 | level, |
454 | 0 | (offered > 0) ? &buffer : NULL, |
455 | 0 | offered, |
456 | 0 | count, |
457 | 0 | info, |
458 | 0 | &needed, |
459 | 0 | &werror); |
460 | 0 | if (!NT_STATUS_IS_OK(status)) { |
461 | 0 | return ntstatus_to_werror(status); |
462 | 0 | } |
463 | | |
464 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
465 | 0 | offered = needed; |
466 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
467 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
468 | | |
469 | 0 | status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx, |
470 | 0 | servername, |
471 | 0 | environment, |
472 | 0 | level, |
473 | 0 | (offered > 0) ? &buffer : NULL, |
474 | 0 | offered, |
475 | 0 | count, |
476 | 0 | info, |
477 | 0 | &needed, |
478 | 0 | &werror); |
479 | 0 | } |
480 | 0 | if (!NT_STATUS_IS_OK(status)) { |
481 | 0 | return ntstatus_to_werror(status); |
482 | 0 | } |
483 | | |
484 | 0 | return werror; |
485 | 0 | } |
486 | | |
487 | | /********************************************************************** |
488 | | convenience wrapper around rpccli_spoolss_EnumPrintProcessorDataTypes |
489 | | **********************************************************************/ |
490 | | |
491 | | WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli, |
492 | | TALLOC_CTX *mem_ctx, |
493 | | const char *servername, |
494 | | const char *print_processor_name, |
495 | | uint32_t level, |
496 | | uint32_t offered, |
497 | | uint32_t *count, |
498 | | union spoolss_PrintProcDataTypesInfo **info) |
499 | 0 | { |
500 | 0 | NTSTATUS status; |
501 | 0 | WERROR werror; |
502 | 0 | uint32_t needed; |
503 | 0 | DATA_BLOB buffer; |
504 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
505 | |
|
506 | 0 | if (offered > 0) { |
507 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
508 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
509 | 0 | } |
510 | | |
511 | 0 | status = dcerpc_spoolss_EnumPrintProcessorDataTypes(b, mem_ctx, |
512 | 0 | servername, |
513 | 0 | print_processor_name, |
514 | 0 | level, |
515 | 0 | (offered > 0) ? &buffer : NULL, |
516 | 0 | offered, |
517 | 0 | count, |
518 | 0 | info, |
519 | 0 | &needed, |
520 | 0 | &werror); |
521 | 0 | if (!NT_STATUS_IS_OK(status)) { |
522 | 0 | return ntstatus_to_werror(status); |
523 | 0 | } |
524 | | |
525 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
526 | 0 | offered = needed; |
527 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
528 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
529 | | |
530 | 0 | status = dcerpc_spoolss_EnumPrintProcessorDataTypes(b, mem_ctx, |
531 | 0 | servername, |
532 | 0 | print_processor_name, |
533 | 0 | level, |
534 | 0 | (offered > 0) ? &buffer : NULL, |
535 | 0 | offered, |
536 | 0 | count, |
537 | 0 | info, |
538 | 0 | &needed, |
539 | 0 | &werror); |
540 | 0 | } |
541 | 0 | if (!NT_STATUS_IS_OK(status)) { |
542 | 0 | return ntstatus_to_werror(status); |
543 | 0 | } |
544 | | |
545 | 0 | return werror; |
546 | 0 | } |
547 | | |
548 | | /********************************************************************** |
549 | | convenience wrapper around rpccli_spoolss_EnumPorts |
550 | | **********************************************************************/ |
551 | | |
552 | | WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli, |
553 | | TALLOC_CTX *mem_ctx, |
554 | | const char *servername, |
555 | | uint32_t level, |
556 | | uint32_t offered, |
557 | | uint32_t *count, |
558 | | union spoolss_PortInfo **info) |
559 | 0 | { |
560 | 0 | NTSTATUS status; |
561 | 0 | WERROR werror; |
562 | 0 | uint32_t needed; |
563 | 0 | DATA_BLOB buffer; |
564 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
565 | |
|
566 | 0 | if (offered > 0) { |
567 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
568 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
569 | 0 | } |
570 | | |
571 | 0 | status = dcerpc_spoolss_EnumPorts(b, mem_ctx, |
572 | 0 | servername, |
573 | 0 | level, |
574 | 0 | (offered > 0) ? &buffer : NULL, |
575 | 0 | offered, |
576 | 0 | count, |
577 | 0 | info, |
578 | 0 | &needed, |
579 | 0 | &werror); |
580 | 0 | if (!NT_STATUS_IS_OK(status)) { |
581 | 0 | return ntstatus_to_werror(status); |
582 | 0 | } |
583 | | |
584 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
585 | 0 | offered = needed; |
586 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
587 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
588 | | |
589 | 0 | status = dcerpc_spoolss_EnumPorts(b, mem_ctx, |
590 | 0 | servername, |
591 | 0 | level, |
592 | 0 | (offered > 0) ? &buffer : NULL, |
593 | 0 | offered, |
594 | 0 | count, |
595 | 0 | info, |
596 | 0 | &needed, |
597 | 0 | &werror); |
598 | 0 | } |
599 | 0 | if (!NT_STATUS_IS_OK(status)) { |
600 | 0 | return ntstatus_to_werror(status); |
601 | 0 | } |
602 | | |
603 | 0 | return werror; |
604 | 0 | } |
605 | | |
606 | | /********************************************************************** |
607 | | convenience wrapper around rpccli_spoolss_EnumMonitors |
608 | | **********************************************************************/ |
609 | | |
610 | | WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli, |
611 | | TALLOC_CTX *mem_ctx, |
612 | | const char *servername, |
613 | | uint32_t level, |
614 | | uint32_t offered, |
615 | | uint32_t *count, |
616 | | union spoolss_MonitorInfo **info) |
617 | 0 | { |
618 | 0 | NTSTATUS status; |
619 | 0 | WERROR werror; |
620 | 0 | uint32_t needed; |
621 | 0 | DATA_BLOB buffer; |
622 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
623 | |
|
624 | 0 | if (offered > 0) { |
625 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
626 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
627 | 0 | } |
628 | | |
629 | 0 | status = dcerpc_spoolss_EnumMonitors(b, mem_ctx, |
630 | 0 | servername, |
631 | 0 | level, |
632 | 0 | (offered > 0) ? &buffer : NULL, |
633 | 0 | offered, |
634 | 0 | count, |
635 | 0 | info, |
636 | 0 | &needed, |
637 | 0 | &werror); |
638 | 0 | if (!NT_STATUS_IS_OK(status)) { |
639 | 0 | return ntstatus_to_werror(status); |
640 | 0 | } |
641 | | |
642 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
643 | 0 | offered = needed; |
644 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
645 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
646 | | |
647 | 0 | status = dcerpc_spoolss_EnumMonitors(b, mem_ctx, |
648 | 0 | servername, |
649 | 0 | level, |
650 | 0 | (offered > 0) ? &buffer : NULL, |
651 | 0 | offered, |
652 | 0 | count, |
653 | 0 | info, |
654 | 0 | &needed, |
655 | 0 | &werror); |
656 | 0 | } |
657 | 0 | if (!NT_STATUS_IS_OK(status)) { |
658 | 0 | return ntstatus_to_werror(status); |
659 | 0 | } |
660 | | |
661 | 0 | return werror; |
662 | 0 | } |
663 | | |
664 | | /********************************************************************** |
665 | | convenience wrapper around rpccli_spoolss_EnumJobs |
666 | | **********************************************************************/ |
667 | | |
668 | | WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, |
669 | | TALLOC_CTX *mem_ctx, |
670 | | struct policy_handle *handle, |
671 | | uint32_t firstjob, |
672 | | uint32_t numjobs, |
673 | | uint32_t level, |
674 | | uint32_t offered, |
675 | | uint32_t *count, |
676 | | union spoolss_JobInfo **info) |
677 | 0 | { |
678 | 0 | NTSTATUS status; |
679 | 0 | WERROR werror; |
680 | 0 | uint32_t needed; |
681 | 0 | DATA_BLOB buffer; |
682 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
683 | |
|
684 | 0 | if (offered > 0) { |
685 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
686 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
687 | 0 | } |
688 | | |
689 | 0 | status = dcerpc_spoolss_EnumJobs(b, mem_ctx, |
690 | 0 | handle, |
691 | 0 | firstjob, |
692 | 0 | numjobs, |
693 | 0 | level, |
694 | 0 | (offered > 0) ? &buffer : NULL, |
695 | 0 | offered, |
696 | 0 | count, |
697 | 0 | info, |
698 | 0 | &needed, |
699 | 0 | &werror); |
700 | 0 | if (!NT_STATUS_IS_OK(status)) { |
701 | 0 | return ntstatus_to_werror(status); |
702 | 0 | } |
703 | | |
704 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
705 | 0 | offered = needed; |
706 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
707 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
708 | | |
709 | 0 | status = dcerpc_spoolss_EnumJobs(b, mem_ctx, |
710 | 0 | handle, |
711 | 0 | firstjob, |
712 | 0 | numjobs, |
713 | 0 | level, |
714 | 0 | (offered > 0) ? &buffer : NULL, |
715 | 0 | offered, |
716 | 0 | count, |
717 | 0 | info, |
718 | 0 | &needed, |
719 | 0 | &werror); |
720 | 0 | } |
721 | 0 | if (!NT_STATUS_IS_OK(status)) { |
722 | 0 | return ntstatus_to_werror(status); |
723 | 0 | } |
724 | | |
725 | 0 | return werror; |
726 | 0 | } |
727 | | |
728 | | /********************************************************************** |
729 | | convenience wrapper around rpccli_spoolss_EnumPrinterDrivers |
730 | | **********************************************************************/ |
731 | | |
732 | | WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli, |
733 | | TALLOC_CTX *mem_ctx, |
734 | | const char *server, |
735 | | const char *environment, |
736 | | uint32_t level, |
737 | | uint32_t offered, |
738 | | uint32_t *count, |
739 | | union spoolss_DriverInfo **info) |
740 | 0 | { |
741 | 0 | NTSTATUS status; |
742 | 0 | WERROR werror; |
743 | 0 | uint32_t needed; |
744 | 0 | DATA_BLOB buffer; |
745 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
746 | |
|
747 | 0 | if (offered > 0) { |
748 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
749 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
750 | 0 | } |
751 | | |
752 | 0 | status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx, |
753 | 0 | server, |
754 | 0 | environment, |
755 | 0 | level, |
756 | 0 | (offered > 0) ? &buffer : NULL, |
757 | 0 | offered, |
758 | 0 | count, |
759 | 0 | info, |
760 | 0 | &needed, |
761 | 0 | &werror); |
762 | 0 | if (!NT_STATUS_IS_OK(status)) { |
763 | 0 | return ntstatus_to_werror(status); |
764 | 0 | } |
765 | | |
766 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
767 | 0 | offered = needed; |
768 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
769 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
770 | | |
771 | 0 | status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx, |
772 | 0 | server, |
773 | 0 | environment, |
774 | 0 | level, |
775 | 0 | (offered > 0) ? &buffer : NULL, |
776 | 0 | offered, |
777 | 0 | count, |
778 | 0 | info, |
779 | 0 | &needed, |
780 | 0 | &werror); |
781 | 0 | } |
782 | 0 | if (!NT_STATUS_IS_OK(status)) { |
783 | 0 | return ntstatus_to_werror(status); |
784 | 0 | } |
785 | | |
786 | 0 | return werror; |
787 | 0 | } |
788 | | |
789 | | /********************************************************************** |
790 | | convenience wrapper around rpccli_spoolss_EnumPrinters |
791 | | **********************************************************************/ |
792 | | |
793 | | WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli, |
794 | | TALLOC_CTX *mem_ctx, |
795 | | uint32_t flags, |
796 | | const char *server, |
797 | | uint32_t level, |
798 | | uint32_t offered, |
799 | | uint32_t *count, |
800 | | union spoolss_PrinterInfo **info) |
801 | 0 | { |
802 | 0 | NTSTATUS status; |
803 | 0 | WERROR werror; |
804 | 0 | uint32_t needed; |
805 | 0 | DATA_BLOB buffer; |
806 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
807 | |
|
808 | 0 | if (offered > 0) { |
809 | 0 | buffer = data_blob_talloc_zero(mem_ctx, offered); |
810 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
811 | 0 | } |
812 | | |
813 | 0 | status = dcerpc_spoolss_EnumPrinters(b, mem_ctx, |
814 | 0 | flags, |
815 | 0 | server, |
816 | 0 | level, |
817 | 0 | (offered > 0) ? &buffer : NULL, |
818 | 0 | offered, |
819 | 0 | count, |
820 | 0 | info, |
821 | 0 | &needed, |
822 | 0 | &werror); |
823 | 0 | if (!NT_STATUS_IS_OK(status)) { |
824 | 0 | return ntstatus_to_werror(status); |
825 | 0 | } |
826 | | |
827 | 0 | if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { |
828 | 0 | offered = needed; |
829 | 0 | buffer = data_blob_talloc_zero(mem_ctx, needed); |
830 | 0 | W_ERROR_HAVE_NO_MEMORY(buffer.data); |
831 | | |
832 | 0 | status = dcerpc_spoolss_EnumPrinters(b, mem_ctx, |
833 | 0 | flags, |
834 | 0 | server, |
835 | 0 | level, |
836 | 0 | (offered > 0) ? &buffer : NULL, |
837 | 0 | offered, |
838 | 0 | count, |
839 | 0 | info, |
840 | 0 | &needed, |
841 | 0 | &werror); |
842 | 0 | } |
843 | 0 | if (!NT_STATUS_IS_OK(status)) { |
844 | 0 | return ntstatus_to_werror(status); |
845 | 0 | } |
846 | | |
847 | 0 | return werror; |
848 | 0 | } |
849 | | |
850 | | /********************************************************************** |
851 | | convenience wrapper around rpccli_spoolss_GetPrinterData |
852 | | **********************************************************************/ |
853 | | |
854 | | WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, |
855 | | TALLOC_CTX *mem_ctx, |
856 | | struct policy_handle *handle, |
857 | | const char *value_name, |
858 | | uint32_t offered, |
859 | | enum winreg_Type *type, |
860 | | uint32_t *needed_p, |
861 | | uint8_t **data_p) |
862 | 0 | { |
863 | 0 | NTSTATUS status; |
864 | 0 | WERROR werror; |
865 | 0 | uint32_t needed; |
866 | 0 | uint8_t *data; |
867 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
868 | |
|
869 | 0 | data = talloc_zero_array(mem_ctx, uint8_t, offered); |
870 | 0 | W_ERROR_HAVE_NO_MEMORY(data); |
871 | | |
872 | 0 | status = dcerpc_spoolss_GetPrinterData(b, mem_ctx, |
873 | 0 | handle, |
874 | 0 | value_name, |
875 | 0 | type, |
876 | 0 | data, |
877 | 0 | offered, |
878 | 0 | &needed, |
879 | 0 | &werror); |
880 | 0 | if (!NT_STATUS_IS_OK(status)) { |
881 | 0 | return ntstatus_to_werror(status); |
882 | 0 | } |
883 | | |
884 | 0 | if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { |
885 | 0 | offered = needed; |
886 | 0 | data = talloc_zero_array(mem_ctx, uint8_t, offered); |
887 | 0 | W_ERROR_HAVE_NO_MEMORY(data); |
888 | | |
889 | 0 | status = dcerpc_spoolss_GetPrinterData(b, mem_ctx, |
890 | 0 | handle, |
891 | 0 | value_name, |
892 | 0 | type, |
893 | 0 | data, |
894 | 0 | offered, |
895 | 0 | &needed, |
896 | 0 | &werror); |
897 | 0 | } |
898 | 0 | if (!NT_STATUS_IS_OK(status)) { |
899 | 0 | return ntstatus_to_werror(status); |
900 | 0 | } |
901 | | |
902 | 0 | *data_p = data; |
903 | 0 | *needed_p = needed; |
904 | |
|
905 | 0 | return werror; |
906 | 0 | } |
907 | | |
908 | | /********************************************************************** |
909 | | convenience wrapper around rpccli_spoolss_EnumPrinterKey |
910 | | **********************************************************************/ |
911 | | |
912 | | WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, |
913 | | TALLOC_CTX *mem_ctx, |
914 | | struct policy_handle *handle, |
915 | | const char *key_name, |
916 | | const char ***key_buffer, |
917 | | uint32_t offered) |
918 | 0 | { |
919 | 0 | NTSTATUS status; |
920 | 0 | WERROR werror; |
921 | 0 | uint32_t needed; |
922 | 0 | union spoolss_KeyNames _key_buffer; |
923 | 0 | uint32_t _ndr_size; |
924 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
925 | |
|
926 | 0 | status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx, |
927 | 0 | handle, |
928 | 0 | key_name, |
929 | 0 | &_ndr_size, |
930 | 0 | &_key_buffer, |
931 | 0 | offered, |
932 | 0 | &needed, |
933 | 0 | &werror); |
934 | 0 | if (!NT_STATUS_IS_OK(status)) { |
935 | 0 | return ntstatus_to_werror(status); |
936 | 0 | } |
937 | | |
938 | 0 | if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { |
939 | 0 | offered = needed; |
940 | 0 | status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx, |
941 | 0 | handle, |
942 | 0 | key_name, |
943 | 0 | &_ndr_size, |
944 | 0 | &_key_buffer, |
945 | 0 | offered, |
946 | 0 | &needed, |
947 | 0 | &werror); |
948 | 0 | } |
949 | 0 | if (!NT_STATUS_IS_OK(status)) { |
950 | 0 | return ntstatus_to_werror(status); |
951 | 0 | } |
952 | | |
953 | 0 | *key_buffer = _key_buffer.string_array; |
954 | |
|
955 | 0 | return werror; |
956 | 0 | } |
957 | | |
958 | | /********************************************************************** |
959 | | convenience wrapper around rpccli_spoolss_EnumPrinterDataEx |
960 | | **********************************************************************/ |
961 | | |
962 | | WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, |
963 | | TALLOC_CTX *mem_ctx, |
964 | | struct policy_handle *handle, |
965 | | const char *key_name, |
966 | | uint32_t offered, |
967 | | uint32_t *count, |
968 | | struct spoolss_PrinterEnumValues **info) |
969 | 0 | { |
970 | 0 | NTSTATUS status; |
971 | 0 | WERROR werror; |
972 | 0 | uint32_t needed; |
973 | 0 | struct dcerpc_binding_handle *b = cli->binding_handle; |
974 | |
|
975 | 0 | status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx, |
976 | 0 | handle, |
977 | 0 | key_name, |
978 | 0 | offered, |
979 | 0 | count, |
980 | 0 | info, |
981 | 0 | &needed, |
982 | 0 | &werror); |
983 | 0 | if (!NT_STATUS_IS_OK(status)) { |
984 | 0 | return ntstatus_to_werror(status); |
985 | 0 | } |
986 | | |
987 | 0 | if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { |
988 | 0 | offered = needed; |
989 | |
|
990 | 0 | status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx, |
991 | 0 | handle, |
992 | 0 | key_name, |
993 | 0 | offered, |
994 | 0 | count, |
995 | 0 | info, |
996 | 0 | &needed, |
997 | 0 | &werror); |
998 | 0 | } |
999 | 0 | if (!NT_STATUS_IS_OK(status)) { |
1000 | 0 | return ntstatus_to_werror(status); |
1001 | 0 | } |
1002 | | |
1003 | 0 | return werror; |
1004 | 0 | } |