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