• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/rpc_client/
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 "../librpc/gen_ndr/cli_spoolss.h"
27
28/**********************************************************************
29 convencience wrapper around rpccli_spoolss_OpenPrinterEx
30**********************************************************************/
31
32WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
33				     TALLOC_CTX *mem_ctx,
34				     const char *printername,
35				     uint32_t access_desired,
36				     struct policy_handle *handle)
37{
38	NTSTATUS status;
39	WERROR werror;
40	struct spoolss_DevmodeContainer devmode_ctr;
41	union spoolss_UserLevel userlevel;
42	struct spoolss_UserLevel1 level1;
43
44	ZERO_STRUCT(devmode_ctr);
45
46	level1.size	= 28;
47	level1.client	= talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
48	W_ERROR_HAVE_NO_MEMORY(level1.client);
49	level1.user	= cli->auth->user_name;
50	level1.build	= 1381;
51	level1.major	= 2;
52	level1.minor	= 0;
53	level1.processor = 0;
54
55	userlevel.level1 = &level1;
56
57	status = rpccli_spoolss_OpenPrinterEx(cli, mem_ctx,
58					      printername,
59					      NULL,
60					      devmode_ctr,
61					      access_desired,
62					      1, /* level */
63					      userlevel,
64					      handle,
65					      &werror);
66
67	if (!W_ERROR_IS_OK(werror)) {
68		return werror;
69	}
70
71	if (!NT_STATUS_IS_OK(status)) {
72		return ntstatus_to_werror(status);
73	}
74
75	return WERR_OK;
76}
77
78/**********************************************************************
79 convencience wrapper around rpccli_spoolss_GetPrinterDriver
80**********************************************************************/
81
82WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli,
83				       TALLOC_CTX *mem_ctx,
84				       struct policy_handle *handle,
85				       const char *architecture,
86				       uint32_t level,
87				       uint32_t offered,
88				       union spoolss_DriverInfo *info)
89{
90	NTSTATUS status;
91	WERROR werror;
92	uint32_t needed;
93	DATA_BLOB buffer;
94
95	if (offered > 0) {
96		buffer = data_blob_talloc_zero(mem_ctx, offered);
97		W_ERROR_HAVE_NO_MEMORY(buffer.data);
98	}
99
100	status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx,
101						 handle,
102						 architecture,
103						 level,
104						 (offered > 0) ? &buffer : NULL,
105						 offered,
106						 info,
107						 &needed,
108						 &werror);
109	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
110		offered = needed;
111		buffer = data_blob_talloc_zero(mem_ctx, needed);
112		W_ERROR_HAVE_NO_MEMORY(buffer.data);
113
114		status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx,
115							 handle,
116							 architecture,
117							 level,
118							 &buffer,
119							 offered,
120							 info,
121							 &needed,
122							 &werror);
123	}
124
125	return werror;
126}
127
128/**********************************************************************
129 convencience wrapper around rpccli_spoolss_GetPrinterDriver2
130**********************************************************************/
131
132WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
133					TALLOC_CTX *mem_ctx,
134					struct policy_handle *handle,
135					const char *architecture,
136					uint32_t level,
137					uint32_t offered,
138					uint32_t client_major_version,
139					uint32_t client_minor_version,
140					union spoolss_DriverInfo *info,
141					uint32_t *server_major_version,
142					uint32_t *server_minor_version)
143{
144	NTSTATUS status;
145	WERROR werror;
146	uint32_t needed;
147	DATA_BLOB buffer;
148
149	if (offered > 0) {
150		buffer = data_blob_talloc_zero(mem_ctx, offered);
151		W_ERROR_HAVE_NO_MEMORY(buffer.data);
152	}
153
154	status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
155						  handle,
156						  architecture,
157						  level,
158						  (offered > 0) ? &buffer : NULL,
159						  offered,
160						  client_major_version,
161						  client_minor_version,
162						  info,
163						  &needed,
164						  server_major_version,
165						  server_minor_version,
166						  &werror);
167	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
168		offered = needed;
169		buffer = data_blob_talloc_zero(mem_ctx, needed);
170		W_ERROR_HAVE_NO_MEMORY(buffer.data);
171
172		status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
173							  handle,
174							  architecture,
175							  level,
176							  &buffer,
177							  offered,
178							  client_major_version,
179							  client_minor_version,
180							  info,
181							  &needed,
182							  server_major_version,
183							  server_minor_version,
184							  &werror);
185	}
186
187	return werror;
188}
189
190/**********************************************************************
191 convencience wrapper around rpccli_spoolss_AddPrinterEx
192**********************************************************************/
193
194WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli,
195				   TALLOC_CTX *mem_ctx,
196				   struct spoolss_SetPrinterInfoCtr *info_ctr)
197{
198	WERROR result;
199	NTSTATUS status;
200	struct spoolss_DevmodeContainer devmode_ctr;
201	struct sec_desc_buf secdesc_ctr;
202	struct spoolss_UserLevelCtr userlevel_ctr;
203	struct spoolss_UserLevel1 level1;
204	struct policy_handle handle;
205
206	ZERO_STRUCT(devmode_ctr);
207	ZERO_STRUCT(secdesc_ctr);
208
209	level1.size		= 28;
210	level1.build		= 1381;
211	level1.major		= 2;
212	level1.minor		= 0;
213	level1.processor	= 0;
214	level1.client		= talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
215	W_ERROR_HAVE_NO_MEMORY(level1.client);
216	level1.user		= cli->auth->user_name;
217
218	userlevel_ctr.level = 1;
219	userlevel_ctr.user_info.level1 = &level1;
220
221	status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx,
222					     cli->srv_name_slash,
223					     info_ctr,
224					     &devmode_ctr,
225					     &secdesc_ctr,
226					     &userlevel_ctr,
227					     &handle,
228					     &result);
229	return result;
230}
231
232/**********************************************************************
233 convencience wrapper around rpccli_spoolss_GetPrinter
234**********************************************************************/
235
236WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli,
237				 TALLOC_CTX *mem_ctx,
238				 struct policy_handle *handle,
239				 uint32_t level,
240				 uint32_t offered,
241				 union spoolss_PrinterInfo *info)
242{
243	NTSTATUS status;
244	WERROR werror;
245	DATA_BLOB buffer;
246	uint32_t needed;
247
248	if (offered > 0) {
249		buffer = data_blob_talloc_zero(mem_ctx, offered);
250		W_ERROR_HAVE_NO_MEMORY(buffer.data);
251	}
252
253	status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
254					   handle,
255					   level,
256					   (offered > 0) ? &buffer : NULL,
257					   offered,
258					   info,
259					   &needed,
260					   &werror);
261
262	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
263
264		offered = needed;
265		buffer = data_blob_talloc_zero(mem_ctx, offered);
266		W_ERROR_HAVE_NO_MEMORY(buffer.data);
267
268		status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
269						   handle,
270						   level,
271						   &buffer,
272						   offered,
273						   info,
274						   &needed,
275						   &werror);
276	}
277
278	return werror;
279}
280
281/**********************************************************************
282 convencience wrapper around rpccli_spoolss_GetJob
283**********************************************************************/
284
285WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
286			     TALLOC_CTX *mem_ctx,
287			     struct policy_handle *handle,
288			     uint32_t job_id,
289			     uint32_t level,
290			     uint32_t offered,
291			     union spoolss_JobInfo *info)
292{
293	NTSTATUS status;
294	WERROR werror;
295	uint32_t needed;
296	DATA_BLOB buffer;
297
298	if (offered > 0) {
299		buffer = data_blob_talloc_zero(mem_ctx, offered);
300		W_ERROR_HAVE_NO_MEMORY(buffer.data);
301	}
302
303	status = rpccli_spoolss_GetJob(cli, mem_ctx,
304				       handle,
305				       job_id,
306				       level,
307				       (offered > 0) ? &buffer : NULL,
308				       offered,
309				       info,
310				       &needed,
311				       &werror);
312
313	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
314		offered = needed;
315		buffer = data_blob_talloc_zero(mem_ctx, needed);
316		W_ERROR_HAVE_NO_MEMORY(buffer.data);
317
318		status = rpccli_spoolss_GetJob(cli, mem_ctx,
319					       handle,
320					       job_id,
321					       level,
322					       &buffer,
323					       offered,
324					       info,
325					       &needed,
326					       &werror);
327	}
328
329	return werror;
330}
331
332/**********************************************************************
333 convencience wrapper around rpccli_spoolss_EnumForms
334**********************************************************************/
335
336WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli,
337				TALLOC_CTX *mem_ctx,
338				struct policy_handle *handle,
339				uint32_t level,
340				uint32_t offered,
341				uint32_t *count,
342				union spoolss_FormInfo **info)
343{
344	NTSTATUS status;
345	WERROR werror;
346	uint32_t needed;
347	DATA_BLOB buffer;
348
349	if (offered > 0) {
350		buffer = data_blob_talloc_zero(mem_ctx, offered);
351		W_ERROR_HAVE_NO_MEMORY(buffer.data);
352	}
353
354	status = rpccli_spoolss_EnumForms(cli, mem_ctx,
355					  handle,
356					  level,
357					  (offered > 0) ? &buffer : NULL,
358					  offered,
359					  count,
360					  info,
361					  &needed,
362					  &werror);
363
364	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
365		offered = needed;
366		buffer = data_blob_talloc_zero(mem_ctx, needed);
367		W_ERROR_HAVE_NO_MEMORY(buffer.data);
368
369		status = rpccli_spoolss_EnumForms(cli, mem_ctx,
370						  handle,
371						  level,
372						  (offered > 0) ? &buffer : NULL,
373						  offered,
374						  count,
375						  info,
376						  &needed,
377						  &werror);
378	}
379
380	return werror;
381}
382
383/**********************************************************************
384 convencience wrapper around rpccli_spoolss_EnumPrintProcessors
385**********************************************************************/
386
387WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli,
388					  TALLOC_CTX *mem_ctx,
389					  const char *servername,
390					  const char *environment,
391					  uint32_t level,
392					  uint32_t offered,
393					  uint32_t *count,
394					  union spoolss_PrintProcessorInfo **info)
395{
396	NTSTATUS status;
397	WERROR werror;
398	uint32_t needed;
399	DATA_BLOB buffer;
400
401	if (offered > 0) {
402		buffer = data_blob_talloc_zero(mem_ctx, offered);
403		W_ERROR_HAVE_NO_MEMORY(buffer.data);
404	}
405
406	status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
407						    servername,
408						    environment,
409						    level,
410						    (offered > 0) ? &buffer : NULL,
411						    offered,
412						    count,
413						    info,
414						    &needed,
415						    &werror);
416
417	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
418		offered = needed;
419		buffer = data_blob_talloc_zero(mem_ctx, needed);
420		W_ERROR_HAVE_NO_MEMORY(buffer.data);
421
422		status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
423							    servername,
424							    environment,
425							    level,
426							    (offered > 0) ? &buffer : NULL,
427							    offered,
428							    count,
429							    info,
430							    &needed,
431							    &werror);
432	}
433
434	return werror;
435}
436
437/**********************************************************************
438 convencience wrapper around rpccli_spoolss_EnumPrintProcDataTypes
439**********************************************************************/
440
441WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli,
442						  TALLOC_CTX *mem_ctx,
443						  const char *servername,
444						  const char *print_processor_name,
445						  uint32_t level,
446						  uint32_t offered,
447						  uint32_t *count,
448						  union spoolss_PrintProcDataTypesInfo **info)
449{
450	NTSTATUS status;
451	WERROR werror;
452	uint32_t needed;
453	DATA_BLOB buffer;
454
455	if (offered > 0) {
456		buffer = data_blob_talloc_zero(mem_ctx, offered);
457		W_ERROR_HAVE_NO_MEMORY(buffer.data);
458	}
459
460	status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
461						       servername,
462						       print_processor_name,
463						       level,
464						       (offered > 0) ? &buffer : NULL,
465						       offered,
466						       count,
467						       info,
468						       &needed,
469						       &werror);
470
471	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
472		offered = needed;
473		buffer = data_blob_talloc_zero(mem_ctx, needed);
474		W_ERROR_HAVE_NO_MEMORY(buffer.data);
475
476		status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
477							       servername,
478							       print_processor_name,
479							       level,
480							       (offered > 0) ? &buffer : NULL,
481							       offered,
482							       count,
483							       info,
484							       &needed,
485							       &werror);
486	}
487
488	return werror;
489}
490
491/**********************************************************************
492 convencience wrapper around rpccli_spoolss_EnumPorts
493**********************************************************************/
494
495WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli,
496				TALLOC_CTX *mem_ctx,
497				const char *servername,
498				uint32_t level,
499				uint32_t offered,
500				uint32_t *count,
501				union spoolss_PortInfo **info)
502{
503	NTSTATUS status;
504	WERROR werror;
505	uint32_t needed;
506	DATA_BLOB buffer;
507
508	if (offered > 0) {
509		buffer = data_blob_talloc_zero(mem_ctx, offered);
510		W_ERROR_HAVE_NO_MEMORY(buffer.data);
511	}
512
513	status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
514					  servername,
515					  level,
516					  (offered > 0) ? &buffer : NULL,
517					  offered,
518					  count,
519					  info,
520					  &needed,
521					  &werror);
522
523	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
524		offered = needed;
525		buffer = data_blob_talloc_zero(mem_ctx, needed);
526		W_ERROR_HAVE_NO_MEMORY(buffer.data);
527
528		status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
529						  servername,
530						  level,
531						  (offered > 0) ? &buffer : NULL,
532						  offered,
533						  count,
534						  info,
535						  &needed,
536						  &werror);
537	}
538
539	return werror;
540}
541
542/**********************************************************************
543 convencience wrapper around rpccli_spoolss_EnumMonitors
544**********************************************************************/
545
546WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
547				   TALLOC_CTX *mem_ctx,
548				   const char *servername,
549				   uint32_t level,
550				   uint32_t offered,
551				   uint32_t *count,
552				   union spoolss_MonitorInfo **info)
553{
554	NTSTATUS status;
555	WERROR werror;
556	uint32_t needed;
557	DATA_BLOB buffer;
558
559	if (offered > 0) {
560		buffer = data_blob_talloc_zero(mem_ctx, offered);
561		W_ERROR_HAVE_NO_MEMORY(buffer.data);
562	}
563
564	status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
565					     servername,
566					     level,
567					     (offered > 0) ? &buffer : NULL,
568					     offered,
569					     count,
570					     info,
571					     &needed,
572					     &werror);
573
574	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
575		offered = needed;
576		buffer = data_blob_talloc_zero(mem_ctx, needed);
577		W_ERROR_HAVE_NO_MEMORY(buffer.data);
578
579		status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
580						     servername,
581						     level,
582						     (offered > 0) ? &buffer : NULL,
583						     offered,
584						     count,
585						     info,
586						     &needed,
587						     &werror);
588	}
589
590	return werror;
591}
592
593/**********************************************************************
594 convencience wrapper around rpccli_spoolss_EnumJobs
595**********************************************************************/
596
597WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli,
598			       TALLOC_CTX *mem_ctx,
599			       struct policy_handle *handle,
600			       uint32_t firstjob,
601			       uint32_t numjobs,
602			       uint32_t level,
603			       uint32_t offered,
604			       uint32_t *count,
605			       union spoolss_JobInfo **info)
606{
607	NTSTATUS status;
608	WERROR werror;
609	uint32_t needed;
610	DATA_BLOB buffer;
611
612	if (offered > 0) {
613		buffer = data_blob_talloc_zero(mem_ctx, offered);
614		W_ERROR_HAVE_NO_MEMORY(buffer.data);
615	}
616
617	status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
618					 handle,
619					 firstjob,
620					 numjobs,
621					 level,
622					 (offered > 0) ? &buffer : NULL,
623					 offered,
624					 count,
625					 info,
626					 &needed,
627					 &werror);
628
629	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
630		offered = needed;
631		buffer = data_blob_talloc_zero(mem_ctx, needed);
632		W_ERROR_HAVE_NO_MEMORY(buffer.data);
633
634		status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
635						 handle,
636						 firstjob,
637						 numjobs,
638						 level,
639						 (offered > 0) ? &buffer : NULL,
640						 offered,
641						 count,
642						 info,
643						 &needed,
644						 &werror);
645	}
646
647	return werror;
648}
649
650/**********************************************************************
651 convencience wrapper around rpccli_spoolss_EnumPrinterDrivers
652**********************************************************************/
653
654WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli,
655					 TALLOC_CTX *mem_ctx,
656					 const char *server,
657					 const char *environment,
658					 uint32_t level,
659					 uint32_t offered,
660					 uint32_t *count,
661					 union spoolss_DriverInfo **info)
662{
663	NTSTATUS status;
664	WERROR werror;
665	uint32_t needed;
666	DATA_BLOB buffer;
667
668	if (offered > 0) {
669		buffer = data_blob_talloc_zero(mem_ctx, offered);
670		W_ERROR_HAVE_NO_MEMORY(buffer.data);
671	}
672
673	status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
674						   server,
675						   environment,
676						   level,
677						   (offered > 0) ? &buffer : NULL,
678						   offered,
679						   count,
680						   info,
681						   &needed,
682						   &werror);
683
684	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
685		offered = needed;
686		buffer = data_blob_talloc_zero(mem_ctx, needed);
687		W_ERROR_HAVE_NO_MEMORY(buffer.data);
688
689		status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
690						   server,
691						   environment,
692						   level,
693						   (offered > 0) ? &buffer : NULL,
694						   offered,
695						   count,
696						   info,
697						   &needed,
698						   &werror);
699	}
700
701	return werror;
702}
703
704/**********************************************************************
705 convencience wrapper around rpccli_spoolss_EnumPrinters
706**********************************************************************/
707
708WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
709				   TALLOC_CTX *mem_ctx,
710				   uint32_t flags,
711				   const char *server,
712				   uint32_t level,
713				   uint32_t offered,
714				   uint32_t *count,
715				   union spoolss_PrinterInfo **info)
716{
717	NTSTATUS status;
718	WERROR werror;
719	uint32_t needed;
720	DATA_BLOB buffer;
721
722	if (offered > 0) {
723		buffer = data_blob_talloc_zero(mem_ctx, offered);
724		W_ERROR_HAVE_NO_MEMORY(buffer.data);
725	}
726
727	status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
728					     flags,
729					     server,
730					     level,
731					     (offered > 0) ? &buffer : NULL,
732					     offered,
733					     count,
734					     info,
735					     &needed,
736					     &werror);
737
738	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
739		offered = needed;
740		buffer = data_blob_talloc_zero(mem_ctx, needed);
741		W_ERROR_HAVE_NO_MEMORY(buffer.data);
742
743		status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
744						     flags,
745						     server,
746						     level,
747						     (offered > 0) ? &buffer : NULL,
748						     offered,
749						     count,
750						     info,
751						     &needed,
752						     &werror);
753	}
754
755	return werror;
756}
757
758/**********************************************************************
759 convencience wrapper around rpccli_spoolss_GetPrinterData
760**********************************************************************/
761
762WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli,
763				     TALLOC_CTX *mem_ctx,
764				     struct policy_handle *handle,
765				     const char *value_name,
766				     uint32_t offered,
767				     enum winreg_Type *type,
768				     uint32_t *needed_p,
769				     uint8_t **data_p)
770{
771	NTSTATUS status;
772	WERROR werror;
773	uint32_t needed;
774	uint8_t *data;
775
776	data = talloc_zero_array(mem_ctx, uint8_t, offered);
777	W_ERROR_HAVE_NO_MEMORY(data);
778
779	status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
780					       handle,
781					       value_name,
782					       type,
783					       data,
784					       offered,
785					       &needed,
786					       &werror);
787
788	if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
789		offered = needed;
790		data = talloc_zero_array(mem_ctx, uint8_t, offered);
791		W_ERROR_HAVE_NO_MEMORY(data);
792
793		status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
794						       handle,
795						       value_name,
796						       type,
797						       data,
798						       offered,
799						       &needed,
800						       &werror);
801	}
802
803	*data_p = data;
804	*needed_p = needed;
805
806	return werror;
807}
808
809/**********************************************************************
810 convencience wrapper around rpccli_spoolss_EnumPrinterKey
811**********************************************************************/
812
813WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli,
814				     TALLOC_CTX *mem_ctx,
815				     struct policy_handle *handle,
816				     const char *key_name,
817				     const char ***key_buffer,
818				     uint32_t offered)
819{
820	NTSTATUS status;
821	WERROR werror;
822	uint32_t needed;
823	union spoolss_KeyNames _key_buffer;
824	uint32_t _ndr_size;
825
826	status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
827					       handle,
828					       key_name,
829					       &_ndr_size,
830					       &_key_buffer,
831					       offered,
832					       &needed,
833					       &werror);
834
835	if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
836		offered = needed;
837		status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
838						       handle,
839						       key_name,
840						       &_ndr_size,
841						       &_key_buffer,
842						       offered,
843						       &needed,
844						       &werror);
845	}
846
847	*key_buffer = _key_buffer.string_array;
848
849	return werror;
850}
851
852/**********************************************************************
853 convencience wrapper around rpccli_spoolss_EnumPrinterDataEx
854**********************************************************************/
855
856WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli,
857					TALLOC_CTX *mem_ctx,
858					struct policy_handle *handle,
859					const char *key_name,
860					uint32_t offered,
861					uint32_t *count,
862					struct spoolss_PrinterEnumValues **info)
863{
864	NTSTATUS status;
865	WERROR werror;
866	uint32_t needed;
867
868	status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
869						  handle,
870						  key_name,
871						  offered,
872						  count,
873						  info,
874						  &needed,
875						  &werror);
876
877	if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
878		offered = needed;
879
880		status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
881							  handle,
882							  key_name,
883							  offered,
884							  count,
885							  info,
886							  &needed,
887							  &werror);
888	}
889
890	return werror;
891}
892