s3-spoolss: remove rpccli_spoolss_addprinterex.
[tprouty/samba.git] / source3 / rpc_client / cli_spoolss.c
index 66d3a6437dce2e13341b17a40b228d13367f8b64..b063a33ca621a07640fc1f78dfe9d0847ce4b011 100644 (file)
@@ -5,12 +5,12 @@
    Copyright (C) Gerald Carter                2001-2005,
    Copyright (C) Tim Potter                   2000-2002,
    Copyright (C) Andrew Tridgell              1994-2000,
-   Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
    Copyright (C) Jean-Francois Micouleau      1999-2000.
+   Copyright (C) Jeremy Allison                         2005.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "rpc_client.h"
 
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_OpenPrinterEx
+**********************************************************************/
+
+WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    const char *printername,
+                                    uint32_t access_desired,
+                                    struct policy_handle *handle)
+{
+       NTSTATUS status;
+       WERROR werror;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       union spoolss_UserLevel userlevel;
+       struct spoolss_UserLevel1 level1;
+
+       ZERO_STRUCT(devmode_ctr);
+
+       level1.size     = 28;
+       level1.client   = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
+       W_ERROR_HAVE_NO_MEMORY(level1.client);
+       level1.user     = cli->auth->user_name;
+       level1.build    = 1381;
+       level1.major    = 2;
+       level1.minor    = 0;
+       level1.processor = 0;
+
+       userlevel.level1 = &level1;
+
+       status = rpccli_spoolss_OpenPrinterEx(cli, mem_ctx,
+                                             printername,
+                                             NULL,
+                                             devmode_ctr,
+                                             access_desired,
+                                             1, /* level */
+                                             userlevel,
+                                             handle,
+                                             &werror);
+
+       if (!W_ERROR_IS_OK(werror)) {
+               return werror;
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return ntstatus_to_werror(status);
+       }
+
+       return WERR_OK;
+}
+
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_GetPrinterDriver2
+**********************************************************************/
+
+WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct policy_handle *handle,
+                                       const char *architecture,
+                                       uint32_t level,
+                                       uint32_t offered,
+                                       uint32_t client_major_version,
+                                       uint32_t client_minor_version,
+                                       union spoolss_DriverInfo *info,
+                                       uint32_t *server_major_version,
+                                       uint32_t *server_minor_version)
+{
+       NTSTATUS status;
+       WERROR werror;
+       uint32_t needed;
+       DATA_BLOB buffer;
+
+       if (offered > 0) {
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
+       }
+
+       status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
+                                                 handle,
+                                                 architecture,
+                                                 level,
+                                                 (offered > 0) ? &buffer : NULL,
+                                                 offered,
+                                                 client_major_version,
+                                                 client_minor_version,
+                                                 info,
+                                                 &needed,
+                                                 server_major_version,
+                                                 server_minor_version,
+                                                 &werror);
+       if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+               offered = needed;
+               buffer = data_blob_talloc_zero(mem_ctx, needed);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
+
+               status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
+                                                         handle,
+                                                         architecture,
+                                                         level,
+                                                         &buffer,
+                                                         offered,
+                                                         client_major_version,
+                                                         client_minor_version,
+                                                         info,
+                                                         &needed,
+                                                         server_major_version,
+                                                         server_minor_version,
+                                                         &werror);
+       }
+
+       return werror;
+}
+
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_AddPrinterEx
+**********************************************************************/
+
+WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct spoolss_SetPrinterInfoCtr *info_ctr)
+{
+       WERROR result;
+       NTSTATUS status;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+       struct spoolss_UserLevelCtr userlevel_ctr;
+       struct spoolss_UserLevel1 level1;
+       struct policy_handle handle;
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+
+       level1.size             = 28;
+       level1.build            = 1381;
+       level1.major            = 2;
+       level1.minor            = 0;
+       level1.processor        = 0;
+       level1.client           = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
+       W_ERROR_HAVE_NO_MEMORY(level1.client);
+       level1.user             = cli->auth->user_name;
+
+       userlevel_ctr.level = 1;
+       userlevel_ctr.user_info.level1 = &level1;
+
+       status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx,
+                                            cli->srv_name_slash,
+                                            info_ctr,
+                                            &devmode_ctr,
+                                            &secdesc_ctr,
+                                            &userlevel_ctr,
+                                            &handle,
+                                            &result);
+       return result;
+}
+
+/**********************************************************************
+ convencience wrapper around rpccli_spoolss_GetPrinter
+**********************************************************************/
+
+WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli,
+                                TALLOC_CTX *mem_ctx,
+                                struct policy_handle *handle,
+                                uint32_t level,
+                                uint32_t offered,
+                                union spoolss_PrinterInfo *info)
+{
+       NTSTATUS status;
+       WERROR werror;
+       DATA_BLOB buffer;
+       uint32_t needed;
+
+       if (offered > 0) {
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
+       }
+
+       status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
+                                          handle,
+                                          level,
+                                          (offered > 0) ? &buffer : NULL,
+                                          offered,
+                                          info,
+                                          &needed,
+                                          &werror);
+
+       if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
+
+               offered = needed;
+               buffer = data_blob_talloc_zero(mem_ctx, offered);
+               W_ERROR_HAVE_NO_MEMORY(buffer.data);
+
+               status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
+                                                  handle,
+                                                  level,
+                                                  &buffer,
+                                                  offered,
+                                                  info,
+                                                  &needed,
+                                                  &werror);
+       }
+
+       return werror;
+}
+
 /*********************************************************************
  Decode various spoolss rpc's and info levels
  ********************************************************************/
 /**********************************************************************
 **********************************************************************/
 
-static void decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
+static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
                                uint32 returned, PRINTER_INFO_0 **info)
 {
-        uint32 i;
-        PRINTER_INFO_0  *inf;
+       uint32 i;
+       PRINTER_INFO_0  *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_0, returned);
-       memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_0, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
-        for (i=0; i<returned; i++) {
-                smb_io_printer_info_0("", buffer, &inf[i], 0);
-        }
+       for (i=0; i<returned; i++) {
+               if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
+
+static bool decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
                                uint32 returned, PRINTER_INFO_1 **info)
 {
-        uint32 i;
-        PRINTER_INFO_1  *inf;
+       uint32 i;
+       PRINTER_INFO_1  *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_1, returned);
-       memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_1, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
-        for (i=0; i<returned; i++) {
-                smb_io_printer_info_1("", buffer, &inf[i], 0);
-        }
+       for (i=0; i<returned; i++) {
+               if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+
+static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                                uint32 returned, PRINTER_INFO_2 **info)
 {
-        uint32 i;
-        PRINTER_INFO_2  *inf;
+       uint32 i;
+       PRINTER_INFO_2  *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_2, returned);
-       memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_2, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
-        for (i=0; i<returned; i++) {
+       for (i=0; i<returned; i++) {
                /* a little initialization as we go */
                inf[i].secdesc = NULL;
-                smb_io_printer_info_2("", buffer, &inf[i], 0);
-        }
+               if (!smb_io_printer_info_2("", buffer, &inf[i], 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+
+static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                                uint32 returned, PRINTER_INFO_3 **info)
 {
-        uint32 i;
-        PRINTER_INFO_3  *inf;
+       uint32 i;
+       PRINTER_INFO_3  *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_3, returned);
-       memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_3, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
-        for (i=0; i<returned; i++) {
+       for (i=0; i<returned; i++) {
                inf[i].secdesc = NULL;
-                smb_io_printer_info_3("", buffer, &inf[i], 0);
-        }
+               if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
+
+static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
                                uint32 returned, PRINTER_INFO_7 **info)
 {
        uint32 i;
        PRINTER_INFO_7  *inf;
 
-       inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned);
-       memset(inf, 0, returned*sizeof(PRINTER_INFO_7));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(PRINTER_INFO_7));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
        for (i=0; i<returned; i++) {
-               smb_io_printer_info_7("", buffer, &inf[i], 0);
+               if (!smb_io_printer_info_7("", buffer, &inf[i], 0)) {
+                       return False;
+               }
        }
 
        *info=inf;
+       return True;
 }
 
 
 /**********************************************************************
 **********************************************************************/
-static void decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+
+static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, PORT_INFO_1 **info)
 {
-        uint32 i;
-        PORT_INFO_1 *inf;
+       uint32 i;
+       PORT_INFO_1 *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_1, returned);
-       memset(inf, 0, returned*sizeof(PORT_INFO_1));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_1, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(PORT_INFO_1));
+       } else {
+               inf = NULL;
+       }
 
-        prs_set_offset(&buffer->prs, 0);
+       prs_set_offset(&buffer->prs, 0);
 
-        for (i=0; i<returned; i++) {
-                smb_io_port_info_1("", buffer, &(inf[i]), 0);
-        }
+       for (i=0; i<returned; i++) {
+               if (!smb_io_port_info_1("", buffer, &(inf[i]), 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+
+static bool decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, PORT_INFO_2 **info)
 {
-        uint32 i;
-        PORT_INFO_2 *inf;
+       uint32 i;
+       PORT_INFO_2 *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_2, returned);
-       memset(inf, 0, returned*sizeof(PORT_INFO_2));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_2, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(PORT_INFO_2));
+       } else {
+               inf = NULL;
+       }
 
-        prs_set_offset(&buffer->prs, 0);
+       prs_set_offset(&buffer->prs, 0);
 
-        for (i=0; i<returned; i++) {
-                smb_io_port_info_2("", buffer, &(inf[i]), 0);
-        }
+       for (i=0; i<returned; i++) {
+               if (!smb_io_port_info_2("", buffer, &(inf[i]), 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+
+static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, DRIVER_INFO_1 **info)
 {
-        uint32 i;
-        DRIVER_INFO_1 *inf;
+       uint32 i;
+       DRIVER_INFO_1 *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_1, returned);
-       memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_1, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
-        for (i=0; i<returned; i++) {
-                smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
-        }
+       for (i=0; i<returned; i++) {
+               if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+
+static bool decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, DRIVER_INFO_2 **info)
 {
-        uint32 i;
-        DRIVER_INFO_2 *inf;
+       uint32 i;
+       DRIVER_INFO_2 *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_2, returned);
-       memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_2, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
-        for (i=0; i<returned; i++) {
-                smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
-        }
+       for (i=0; i<returned; i++) {
+               if (!smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0)) {
+                       return False;
+               }
+       }
 
-        *info=inf;
+       *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
-static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+
+static bool decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                        uint32 returned, DRIVER_INFO_3 **info)
 {
-        uint32 i;
-        DRIVER_INFO_3 *inf;
+       uint32 i;
+       DRIVER_INFO_3 *inf;
 
-        inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_3, returned);
-       memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
+       if (returned) {
+               inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_3, returned);
+               if (!inf) {
+                       return False;
+               }
+               memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
+       } else {
+               inf = NULL;
+       }
 
        prs_set_offset(&buffer->prs,0);
 
-        for (i=0; i<returned; i++) {
-                smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
-        }
-
-        *info=inf;
-}
-
-/**********************************************************************
-**********************************************************************/
-static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
-                       uint32 returned, DRIVER_DIRECTORY_1 **info
-)
-{
-       DRIVER_DIRECTORY_1 *inf;
-        inf=TALLOC_P(mem_ctx, DRIVER_DIRECTORY_1);
-       memset(inf, 0, sizeof(DRIVER_DIRECTORY_1));
-
-        prs_set_offset(&buffer->prs, 0);
+       for (i=0; i<returned; i++) {
+               if (!smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0)) {
+                       return False;
+               }
+       }
 
-        smb_io_driverdir_1("", buffer, inf, 0);
        *info=inf;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
 
-static void decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                          uint32 num_jobs, JOB_INFO_1 **jobs)
 {
        uint32 i;
 
-       *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_1, num_jobs);
+       if (num_jobs) {
+               *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_1, num_jobs);
+               if (*jobs == NULL) {
+                       return False;
+               }
+       } else {
+               *jobs = NULL;
+       }
        prs_set_offset(&buffer->prs,0);
 
-       for (i = 0; i < num_jobs; i++) 
-               smb_io_job_info_1("", buffer, &((*jobs)[i]), 0);
+       for (i = 0; i < num_jobs; i++) {
+               if (!smb_io_job_info_1("", buffer, &((*jobs)[i]), 0)) {
+                       return False;
+               }
+       }
+
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
 
-static void decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                          uint32 num_jobs, JOB_INFO_2 **jobs)
 {
        uint32 i;
 
-       *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_2, num_jobs);
+       if (num_jobs) {
+               *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_2, num_jobs);
+               if (*jobs == NULL) {
+                       return False;
+               }
+       } else {
+               *jobs = NULL;
+       }
        prs_set_offset(&buffer->prs,0);
 
-       for (i = 0; i < num_jobs; i++) 
-               smb_io_job_info_2("", buffer, &((*jobs)[i]), 0);
+       for (i = 0; i < num_jobs; i++) {
+               if (!smb_io_job_info_2("", buffer, &((*jobs)[i]), 0)) {
+                       return False;
+               }
+       }
+
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
 
-static void decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
+static bool decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
                           uint32 num_forms, FORM_1 **forms)
 {
        int i;
 
-       *forms = TALLOC_ARRAY(mem_ctx, FORM_1, num_forms);
-       prs_set_offset(&buffer->prs,0);
-
-       for (i = 0; i < num_forms; i++)
-               smb_io_form_1("", buffer, &((*forms)[i]), 0);
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                               const char *printername, const char *datatype, uint32 access_required,
-                               const char *station, const char *username, POLICY_HND *pol)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_OPEN_PRINTER_EX in;
-       SPOOL_R_OPEN_PRINTER_EX out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_open_printer_ex( &in, printername, datatype,
-               access_required, station, username );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_OPENPRINTEREX,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_open_printer_ex,
-                   spoolss_io_r_open_printer_ex, 
-                   WERR_GENERAL_FAILURE );
-
-       memcpy( pol, &out.handle, sizeof(POLICY_HND) );
-       
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                POLICY_HND *pol)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_CLOSEPRINTER in;
-       SPOOL_R_CLOSEPRINTER out;
+       if (num_forms) {
+               *forms = TALLOC_ARRAY(mem_ctx, FORM_1, num_forms);
+               if (*forms == NULL) {
+                       return False;
+               }
+       } else {
+               *forms = NULL;
+       }
 
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
+       prs_set_offset(&buffer->prs,0);
 
-        make_spoolss_q_closeprinter( &in, pol );
+       for (i = 0; i < num_forms; i++) {
+               if (!smb_io_form_1("", buffer, &((*forms)[i]), 0)) {
+                       return False;
+               }
+       }
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_CLOSEPRINTER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_closeprinter,
-                   spoolss_io_r_closeprinter, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
+       return True;
 }
 
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                 char *name, uint32 flags, uint32 level,
                                 uint32 *num_printers, PRINTER_INFO_CTR *ctr)
 {
@@ -369,10 +645,11 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(out);
 
        offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
+       if (!rpcbuf_init(&buffer, offered, mem_ctx))
+               return WERR_NOMEM;
        make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERS,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_enumprinters,
@@ -385,10 +662,11 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                ZERO_STRUCT(in);
                ZERO_STRUCT(out);
 
-               rpcbuf_init(&buffer, offered, mem_ctx);
+               if (!rpcbuf_init(&buffer, offered, mem_ctx))
+                       return WERR_NOMEM;
                make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERS,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_enumprinters,
@@ -401,19 +679,29 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        switch (level) {
        case 0:
-               decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0);
+               if (!decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 1:
-               decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1);
+               if (!decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 2:
-               decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2);
+               if (!decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 3:
-               decode_printer_info_3(mem_ctx, out.buffer, out.returned, &ctr->printers_3);
+               if (!decode_printer_info_3(mem_ctx, out.buffer, out.returned, &ctr->printers_3)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
+       default:
+               return WERR_UNKNOWN_LEVEL;
        }                       
-       
+
        *num_printers = out.returned;
 
        return out.status;
@@ -422,7 +710,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                              uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
@@ -439,10 +727,11 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
         strupper_m(server);
 
        offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
+       if (!rpcbuf_init(&buffer, offered, mem_ctx))
+               return WERR_NOMEM;
        make_spoolss_q_enumports( &in, server, level, &buffer, offered );
        
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPORTS,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_enumports,
@@ -455,10 +744,11 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                ZERO_STRUCT(in);
                ZERO_STRUCT(out);
                
-               rpcbuf_init(&buffer, offered, mem_ctx);
+               if (!rpcbuf_init(&buffer, offered, mem_ctx))
+                       return WERR_NOMEM;
                make_spoolss_q_enumports( &in, server, level, &buffer, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPORTS,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_enumports,
@@ -471,12 +761,18 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        
        switch (level) {
        case 1:
-               decode_port_info_1(mem_ctx, out.buffer, out.returned, &ctr->port.info_1);
+               if (!decode_port_info_1(mem_ctx, out.buffer, out.returned, &ctr->port.info_1)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 2:
-               decode_port_info_2(mem_ctx, out.buffer, out.returned, &ctr->port.info_2);
+               if (!decode_port_info_2(mem_ctx, out.buffer, out.returned, &ctr->port.info_2)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
-       }                       
+       default:
+               return WERR_UNKNOWN_LEVEL;
+       }
 
        *num_ports = out.returned;
 
@@ -486,7 +782,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                              POLICY_HND *pol, uint32 level, 
                              PRINTER_INFO_CTR *ctr)
 {
@@ -502,10 +798,11 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        /* Initialise input parameters */
 
        offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
+       if (!rpcbuf_init(&buffer, offered, mem_ctx))
+               return WERR_NOMEM;
        make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
        
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTER,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_getprinter,
@@ -518,10 +815,11 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                ZERO_STRUCT(in);
                ZERO_STRUCT(out);
                
-               rpcbuf_init(&buffer, offered, mem_ctx);
+               if (!rpcbuf_init(&buffer, offered, mem_ctx))
+                       return WERR_NOMEM;
                make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTER,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_getprinter,
@@ -534,21 +832,33 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                
        switch (level) {
        case 0:
-               decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0);
+               if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 1:
-               decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1);
+               if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 2:
-               decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2);
+               if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 3:
-               decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3);
+               if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 7:
-               decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7);
+               if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
-       }                       
+       default:
+               return WERR_UNKNOWN_LEVEL;
+       }
 
        return out.status;
 }
@@ -556,7 +866,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                              POLICY_HND *pol, uint32 level, 
                              PRINTER_INFO_CTR *ctr, uint32 command)
 {
@@ -569,7 +879,7 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTER,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_setprinter,
@@ -582,76 +892,7 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, 
-                                   TALLOC_CTX *mem_ctx, 
-                                   POLICY_HND *pol, uint32 level, 
-                                   const char *env, int version, PRINTER_DRIVER_CTR *ctr)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_GETPRINTERDRIVER2 in;
-        SPOOL_R_GETPRINTERDRIVER2 out;
-       RPC_BUFFER buffer;
-       fstring server;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       fstrcpy(server, cli->desthost);
-       strupper_m(server);
-
-       offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
-       make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
-               version, 2, &buffer, offered);
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVER2,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_getprinterdriver2,
-                   spoolss_io_r_getprinterdriver2, 
-                   WERR_GENERAL_FAILURE );
-                   
-       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               rpcbuf_init(&buffer, offered, mem_ctx);
-               make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
-                       version, 2, &buffer, offered);
-
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVER2,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_getprinterdriver2,
-                           spoolss_io_r_getprinterdriver2, 
-                           WERR_GENERAL_FAILURE );
-       }
-               
-       if ( !W_ERROR_IS_OK(out.status) )
-               return out.status;
-
-       switch (level) {
-       case 1:
-               decode_printer_driver_1(mem_ctx, out.buffer, 1, &ctr->info1);
-               break;
-       case 2:
-               decode_printer_driver_2(mem_ctx, out.buffer, 1, &ctr->info2);
-               break;
-       case 3:
-               decode_printer_driver_3(mem_ctx, out.buffer, 1, &ctr->info3);
-               break;
-       }
-
-       return out.status;      
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, 
+WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, 
                                       TALLOC_CTX *mem_ctx,
                                       uint32 level, const char *env,
                                       uint32 *num_drivers,
@@ -671,11 +912,12 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
         strupper_m(server);
 
        offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
+       if (!rpcbuf_init(&buffer, offered, mem_ctx))
+               return WERR_NOMEM;
        make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
                &buffer, offered);
        
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDRIVERS,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_enumprinterdrivers,
@@ -688,11 +930,12 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
                ZERO_STRUCT(in);
                ZERO_STRUCT(out);
                
-               rpcbuf_init(&buffer, offered, mem_ctx);
+               if (!rpcbuf_init(&buffer, offered, mem_ctx))
+                       return WERR_NOMEM;
                make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
                        &buffer, offered);
        
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDRIVERS,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_enumprinterdrivers,
@@ -709,439 +952,82 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
 
                switch (level) {
                case 1:
-                       decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1);
+                       if (!decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1)) {
+                               return WERR_GENERAL_FAILURE;
+                       }
                        break;
                case 2:
-                       decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2);
+                       if (!decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2)) {
+                               return WERR_GENERAL_FAILURE;
+                       }
                        break;
                case 3:
-                       decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3);
+                       if (!decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3)) {
+                               return WERR_GENERAL_FAILURE;
+                       }
                        break;
+               default:
+                       return WERR_UNKNOWN_LEVEL;
                }
        }
 
        return out.status;
 }
 
-
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, 
-                                       TALLOC_CTX *mem_ctx,
-                                       uint32 level, char *env,
-                                       DRIVER_DIRECTORY_CTR *ctr)
+WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+                            POLICY_HND *handle, int level, uint32 *num_forms,
+                            FORM_1 **forms)
 {
        prs_struct qbuf, rbuf;
-       SPOOL_Q_GETPRINTERDRIVERDIR in;
-        SPOOL_R_GETPRINTERDRIVERDIR out;
+       SPOOL_Q_ENUMFORMS in;
+       SPOOL_R_ENUMFORMS out;
        RPC_BUFFER buffer;
-       fstring server;
        uint32 offered;
 
        ZERO_STRUCT(in);
        ZERO_STRUCT(out);
 
-        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper_m(server);
-
        offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
-       make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
-               &buffer, offered );
+       if (!rpcbuf_init(&buffer, offered, mem_ctx))
+               return WERR_NOMEM;
+       make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
                    in, out, 
                    qbuf, rbuf,
-                   spoolss_io_q_getprinterdriverdir,
-                   spoolss_io_r_getprinterdriverdir
+                   spoolss_io_q_enumforms,
+                   spoolss_io_r_enumforms
                    WERR_GENERAL_FAILURE );
-                   
+
        if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
                offered = out.needed;
                
                ZERO_STRUCT(in);
                ZERO_STRUCT(out);
-               
-               rpcbuf_init(&buffer, offered, mem_ctx);
-               make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
-                       &buffer, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
+               if (!rpcbuf_init(&buffer, offered, mem_ctx))
+                       return WERR_NOMEM;
+               make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
+
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
                            in, out, 
                            qbuf, rbuf,
-                           spoolss_io_q_getprinterdriverdir,
-                           spoolss_io_r_getprinterdriverdir
+                           spoolss_io_q_enumforms,
+                           spoolss_io_r_enumforms
                            WERR_GENERAL_FAILURE );
        }
-       
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;
-               
-       decode_printerdriverdir_1(mem_ctx, out.buffer, 1, &ctr->info1);
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_addprinterdriver (struct cli_state *cli, 
-                                    TALLOC_CTX *mem_ctx, uint32 level,
-                                    PRINTER_DRIVER_CTR *ctr)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ADDPRINTERDRIVER in;
-        SPOOL_R_ADDPRINTERDRIVER out;
-       fstring server;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-       
-        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper_m(server);
-
-       make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDPRINTERDRIVER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_addprinterdriver,
-                   spoolss_io_r_addprinterdriver, 
-                   WERR_GENERAL_FAILURE );
-
-       return out.status;                  
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                uint32 level, PRINTER_INFO_CTR*ctr)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ADDPRINTEREX in;
-        SPOOL_R_ADDPRINTEREX out;
-       fstring server, client, user;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-       
-        slprintf(client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-       
-        strupper_m(client);
-        strupper_m(server);
-
-       fstrcpy  (user, cli->user_name);
-
-       make_spoolss_q_addprinterex( mem_ctx, &in, server, client, 
-               user, level, ctr);
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDPRINTEREX,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_addprinterex,
-                   spoolss_io_r_addprinterex, 
-                   WERR_GENERAL_FAILURE );
-
-       return out.status;      
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_deleteprinterdriverex(struct cli_state *cli, 
-                                         TALLOC_CTX *mem_ctx, const char *arch,
-                                         const char *driver, int version)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_DELETEPRINTERDRIVEREX in;
-       SPOOL_R_DELETEPRINTERDRIVEREX out;
-       fstring server;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-       strupper_m(server);
-
-       make_spoolss_q_deleteprinterdriverex( mem_ctx, &in, server, arch, driver, version );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVEREX,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_deleteprinterdriverex,
-                   spoolss_io_r_deleteprinterdriverex, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;      
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, 
-                                       TALLOC_CTX *mem_ctx, const char *arch,
-                                       const char *driver)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_DELETEPRINTERDRIVER in;
-        SPOOL_R_DELETEPRINTERDRIVER out;
-       fstring server;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
-        strupper_m(server);
-
-       make_spoolss_q_deleteprinterdriver( mem_ctx, &in, server, arch, driver );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_deleteprinterdriver,
-                   spoolss_io_r_deleteprinterdriver, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;      
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
-                                             TALLOC_CTX *mem_ctx,
-                                             char *name, char *environment,
-                                             fstring procdir)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_GETPRINTPROCESSORDIRECTORY in;
-       SPOOL_R_GETPRINTPROCESSORDIRECTORY out;
-       int level = 1;
-       RPC_BUFFER buffer;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
-       make_spoolss_q_getprintprocessordirectory( &in, name, 
-               environment, level, &buffer, offered );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_getprintprocessordirectory,
-                   spoolss_io_r_getprintprocessordirectory, 
-                   WERR_GENERAL_FAILURE );
-                   
-       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               rpcbuf_init(&buffer, offered, mem_ctx);
-               make_spoolss_q_getprintprocessordirectory( &in, name, 
-                       environment, level, &buffer, offered );
-
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_getprintprocessordirectory,
-                           spoolss_io_r_getprintprocessordirectory, 
-                           WERR_GENERAL_FAILURE );
-       }
-       
-       if ( !W_ERROR_IS_OK(out.status) )
-               return out.status;
-       
-       fstrcpy(procdir, "Not implemented!");
-       
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                          POLICY_HND *handle, uint32 level, FORM *form)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ADDFORM in;
-       SPOOL_R_ADDFORM out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_addform( &in, handle, level, form );
-       
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDFORM,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_addform,
-                   spoolss_io_r_addform, 
-                   WERR_GENERAL_FAILURE );
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                          POLICY_HND *handle, uint32 level, 
-                          const char *form_name, FORM *form)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_SETFORM in;
-       SPOOL_R_SETFORM out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_setform( &in, handle, level, form_name, form );
-       
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETFORM,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_setform,
-                   spoolss_io_r_setform, 
-                   WERR_GENERAL_FAILURE );
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                          POLICY_HND *handle, const char *formname, 
-                          uint32 level, FORM_1 *form)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_GETFORM in;
-       SPOOL_R_GETFORM out;
-       RPC_BUFFER buffer;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
-       make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
-       
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETFORM,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_getform,
-                   spoolss_io_r_getform, 
-                   WERR_GENERAL_FAILURE );
-                   
-       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               rpcbuf_init(&buffer, offered, mem_ctx);
-               make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
-       
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETFORM,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_getform,
-                           spoolss_io_r_getform, 
-                           WERR_GENERAL_FAILURE );
-       }
-       
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;
-
-       smb_io_form_1("", out.buffer, form, 0);
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                             POLICY_HND *handle, const char *form_name)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_DELETEFORM in;
-       SPOOL_R_DELETEFORM out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_deleteform( &in, handle, form_name );
-       
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEFORM,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_deleteform,
-                   spoolss_io_r_deleteform, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                            POLICY_HND *handle, int level, uint32 *num_forms,
-                            FORM_1 **forms)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENUMFORMS in;
-       SPOOL_R_ENUMFORMS out;
-       RPC_BUFFER buffer;
-       uint32 offered;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
-       make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMFORMS,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enumforms,
-                   spoolss_io_r_enumforms, 
-                   WERR_GENERAL_FAILURE );
-
-       if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-
-               rpcbuf_init(&buffer, offered, mem_ctx);
-               make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
-
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMFORMS,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_enumforms,
-                           spoolss_io_r_enumforms, 
-                           WERR_GENERAL_FAILURE );
-       }
-
+
        if (!W_ERROR_IS_OK(out.status))
                return out.status;
 
        *num_forms = out.numofforms;
        
-       decode_forms_1(mem_ctx, out.buffer, *num_forms, forms);
+       if (!decode_forms_1(mem_ctx, out.buffer, *num_forms, forms)) {
+               return WERR_GENERAL_FAILURE;
+       }
 
        return out.status;
 }
@@ -1149,7 +1035,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                            POLICY_HND *hnd, uint32 level, uint32 firstjob, 
                            uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
 {
@@ -1163,11 +1049,12 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(out);
 
        offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
+       if (!rpcbuf_init(&buffer, offered, mem_ctx))
+               return WERR_NOMEM;
        make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
                &buffer, offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMJOBS,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_enumjobs,
@@ -1180,11 +1067,12 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                ZERO_STRUCT(in);
                ZERO_STRUCT(out);
 
-               rpcbuf_init(&buffer, offered, mem_ctx);
+               if (!rpcbuf_init(&buffer, offered, mem_ctx))
+                       return WERR_NOMEM;
                make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
                        &buffer, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMJOBS,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_enumjobs,
@@ -1197,14 +1085,18 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                
        switch(level) {
        case 1:
-               decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1);
+               if (!decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 2:
-               decode_jobs_2(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_2);
+               if (!decode_jobs_2(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_2)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        default:
                DEBUG(3, ("unsupported info level %d", level));
-               break;
+               return WERR_UNKNOWN_LEVEL;
        }
        
        *returned = out.returned;
@@ -1215,33 +1107,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                         POLICY_HND *hnd, uint32 jobid, uint32 level, 
-                         uint32 command)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_SETJOB in;
-       SPOOL_R_SETJOB out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_setjob( &in, hnd, jobid, level, command );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETJOB,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_setjob,
-                   spoolss_io_r_setjob, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                          POLICY_HND *hnd, uint32 jobid, uint32 level,
                          JOB_INFO_CTR *ctr)
 {
@@ -1255,10 +1121,11 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(out);
 
        offered = 0;
-       rpcbuf_init(&buffer, offered, mem_ctx);
+       if (!rpcbuf_init(&buffer, offered, mem_ctx))
+               return WERR_NOMEM;
        make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETJOB,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_getjob,
@@ -1271,10 +1138,11 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                ZERO_STRUCT(in);
                ZERO_STRUCT(out);
                
-               rpcbuf_init(&buffer, offered, mem_ctx);
+               if (!rpcbuf_init(&buffer, offered, mem_ctx))
+                       return WERR_NOMEM;
                make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETJOB,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_getjob,
@@ -1287,11 +1155,17 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        switch(level) {
        case 1:
-               decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1);
+               if (!decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
        case 2:
-               decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2);
+               if (!decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2)) {
+                       return WERR_GENERAL_FAILURE;
+               }
                break;
+       default:
+               return WERR_UNKNOWN_LEVEL;
        }
 
        return out.status;
@@ -1300,113 +1174,7 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                   POLICY_HND *hnd)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_STARTPAGEPRINTER in;
-       SPOOL_R_STARTPAGEPRINTER out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_startpageprinter( &in, hnd );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_STARTPAGEPRINTER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_startpageprinter,
-                   spoolss_io_r_startpageprinter, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENDPAGEPRINTER in;
-       SPOOL_R_ENDPAGEPRINTER out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_endpageprinter( &in, hnd );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENDPAGEPRINTER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_endpageprinter,
-                   spoolss_io_r_endpageprinter, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                  POLICY_HND *hnd, char *docname, 
-                                  char *outputfile, char *datatype, 
-                                  uint32 *jobid)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_STARTDOCPRINTER in;
-       SPOOL_R_STARTDOCPRINTER out;
-       uint32 level = 1;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_startdocprinter( &in, hnd, level, docname, 
-               outputfile, datatype );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_STARTDOCPRINTER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_startdocprinter,
-                   spoolss_io_r_startdocprinter, 
-                   WERR_GENERAL_FAILURE );
-
-       *jobid = out.jobid;
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                 POLICY_HND *hnd)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_ENDDOCPRINTER in;
-       SPOOL_R_ENDDOCPRINTER out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_enddocprinter( &in, hnd );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENDDOCPRINTER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_enddocprinter,
-                   spoolss_io_r_enddocprinter, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                  POLICY_HND *hnd, const char *valuename, 
                                  REGISTRY_VALUE *value)
 {
@@ -1421,7 +1189,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        offered = 0;
        make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATA,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_getprinterdata,
@@ -1436,7 +1204,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                
                make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATA,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_getprinterdata,
@@ -1449,7 +1217,11 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Return output parameters */
 
-       value->data_p = TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
+       if (out.needed) {
+               value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
+       } else {
+               value->data_p = NULL;
+       }
        value->type = out.type;
        value->size = out.size;
 
@@ -1459,60 +1231,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                   POLICY_HND *hnd, const char *keyname, 
-                                   const char *valuename, 
-                                   REGISTRY_VALUE *value)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_GETPRINTERDATAEX in;
-       SPOOL_R_GETPRINTERDATAEX out;
-       uint32 offered = 0;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-       make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATAEX,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_getprinterdataex,
-                   spoolss_io_r_getprinterdataex, 
-                   WERR_GENERAL_FAILURE );
-
-       if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
-               offered = out.needed;
-               
-               ZERO_STRUCT(in);
-               ZERO_STRUCT(out);
-               
-               make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
-
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATAEX,
-                           in, out, 
-                           qbuf, rbuf,
-                           spoolss_io_q_getprinterdataex,
-                           spoolss_io_r_getprinterdataex, 
-                           WERR_GENERAL_FAILURE );
-       }
-
-       if (!W_ERROR_IS_OK(out.status))
-               return out.status;      
-
-       /* Return output parameters */
-
-       value->data_p = TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
-       value->type = out.type;
-       value->size = out.needed;
-       
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                  POLICY_HND *hnd, REGISTRY_VALUE *value)
 {
        prs_struct qbuf, rbuf;
@@ -1525,7 +1244,7 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
         make_spoolss_q_setprinterdata( &in, hnd, value->valuename, 
                value->type, (char *)value->data_p, value->size);
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTERDATA,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATA,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_setprinterdata,
@@ -1538,34 +1257,7 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                   POLICY_HND *hnd, char *keyname, 
-                                   REGISTRY_VALUE *value)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_SETPRINTERDATAEX in;
-       SPOOL_R_SETPRINTERDATAEX out;
-       
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_setprinterdataex( &in, hnd, keyname, value->valuename, 
-               value->type, (char *)value->data_p, value->size);
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTERDATAEX,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_setprinterdataex,
-                   spoolss_io_r_setprinterdataex, 
-                   WERR_GENERAL_FAILURE );
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                   POLICY_HND *hnd, uint32 ndx,
                                   uint32 value_offered, uint32 data_offered,
                                   uint32 *value_needed, uint32 *data_needed,
@@ -1580,7 +1272,7 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
         make_spoolss_q_enumprinterdata( &in, hnd, ndx, value_offered, data_offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATA,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATA,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_enumprinterdata,
@@ -1589,7 +1281,7 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        if ( value_needed )
                *value_needed = out.realvaluesize;
-       if ( data_offered )
+       if ( data_needed )
                *data_needed = out.realdatasize;
                
        if (!W_ERROR_IS_OK(out.status))
@@ -1598,7 +1290,12 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        if (value) {
                rpcstr_pull(value->valuename, out.value, sizeof(value->valuename), -1,
                            STR_TERMINATE);
-               value->data_p = TALLOC_MEMDUP(mem_ctx, out.data, out.realdatasize);
+               if (out.realdatasize) {
+                       value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data,
+                                                      out.realdatasize);
+               } else {
+                       value->data_p = NULL;
+               }
                value->type = out.type;
                value->size = out.realdatasize;
        }
@@ -1609,7 +1306,7 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                     POLICY_HND *hnd, const char *keyname, 
                                     REGVAL_CTR *ctr)
 {
@@ -1625,7 +1322,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        offered = 0;
        make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATAEX,
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_enumprinterdataex,
@@ -1640,7 +1337,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                
                make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATAEX,
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_enumprinterdataex,
@@ -1651,8 +1348,6 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        if (!W_ERROR_IS_OK(out.status))
                return out.status;
 
-       regval_ctr_init(ctr);
-
        for (i = 0; i < out.returned; i++) {
                PRINTER_ENUM_VALUES *v = &out.ctr.values[i];
                fstring name;
@@ -1668,87 +1363,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
 **********************************************************************/
 
-WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                               POLICY_HND *hnd, uint32 data_size, char *data,
-                               uint32 *num_written)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_WRITEPRINTER in;
-       SPOOL_R_WRITEPRINTER out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_writeprinter( &in, hnd, data_size, data );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_WRITEPRINTER,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_writeprinter,
-                   spoolss_io_r_writeprinter, 
-                   WERR_GENERAL_FAILURE );
-                   
-       if (num_written)
-               *num_written = out.buffer_written;
-               
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                    POLICY_HND *hnd, char *valuename)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_DELETEPRINTERDATA in;
-       SPOOL_R_DELETEPRINTERDATA out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_deleteprinterdata( &in, hnd, valuename );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATA,
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_deleteprinterdata,
-                   spoolss_io_r_deleteprinterdata, 
-                   WERR_GENERAL_FAILURE );
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                      POLICY_HND *hnd, char *keyname, 
-                                      char *valuename)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_DELETEPRINTERDATAEX in;
-       SPOOL_R_DELETEPRINTERDATAEX out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_deleteprinterdataex( &in, hnd, keyname, valuename );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATAEX, 
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_deleteprinterdataex,
-                   spoolss_io_r_deleteprinterdataex, 
-                   WERR_GENERAL_FAILURE );
-
-       return out.status;
-}
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                                  POLICY_HND *hnd, const char *keyname,
                                  uint16 **keylist, uint32 *len)
 {
@@ -1762,7 +1377,7 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
 
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERKEY, 
+       CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_enumprinterkey,
@@ -1777,7 +1392,7 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                
                make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
 
-               CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERKEY, 
+               CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
                            in, out, 
                            qbuf, rbuf,
                            spoolss_io_q_enumprinterkey,
@@ -1790,6 +1405,9 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        
        if (keylist) {
                *keylist = SMB_MALLOC_ARRAY(uint16, out.keys.buf_len);
+               if (!*keylist) {
+                       return WERR_NOMEM;
+               }
                memcpy(*keylist, out.keys.buffer, out.keys.buf_len * 2);
                if (len)
                        *len = out.keys.buf_len * 2;
@@ -1797,30 +1415,4 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        return out.status;
 }
-
-/**********************************************************************
-**********************************************************************/
-
-WERROR cli_spoolss_deleteprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                                   POLICY_HND *hnd, char *keyname)
-{
-       prs_struct qbuf, rbuf;
-       SPOOL_Q_DELETEPRINTERKEY in;
-       SPOOL_R_DELETEPRINTERKEY out;
-
-       ZERO_STRUCT(in);
-       ZERO_STRUCT(out);
-
-        make_spoolss_q_deleteprinterkey( &in, hnd, keyname );
-
-       CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERKEY, 
-                   in, out, 
-                   qbuf, rbuf,
-                   spoolss_io_q_deleteprinterkey,
-                   spoolss_io_r_deleteprinterkey, 
-                   WERR_GENERAL_FAILURE );
-                   
-       return out.status;
-}
-
 /** @} **/