diff options
Diffstat (limited to 'source3/rpc_client/cli_spoolss.c')
-rw-r--r-- | source3/rpc_client/cli_spoolss.c | 603 |
1 files changed, 129 insertions, 474 deletions
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index a83b0c53c6..76614c67eb 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -540,519 +540,174 @@ WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli, return werror; } -/********************************************************************* - Decode various spoolss rpc's and info levels - ********************************************************************/ - -/********************************************************************** -**********************************************************************/ - -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; - - 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++) { - if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) { - return False; - } - } - - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -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; - - 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++) { - if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) { - return False; - } - } - - *info=inf; - return True; -} - /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumJobs **********************************************************************/ -static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_2 **info) +WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t firstjob, + uint32_t numjobs, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_JobInfo **info) { - uint32 i; - PRINTER_INFO_2 *inf; - - 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++) { - /* a little initialization as we go */ - inf[i].secdesc = NULL; - if (!smb_io_printer_info_2("", buffer, &inf[i], 0)) { - return False; - } - } - - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -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; - - 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++) { - inf[i].secdesc = NULL; - if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) { - return False; - } - } - - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -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; - - 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++) { - if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) { - return False; - } - } - - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -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; - - 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); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i=0; i<returned; i++) { - if (!smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - *info=inf; - return True; -} - -/********************************************************************** -**********************************************************************/ - -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; + status = rpccli_spoolss_EnumJobs(cli, mem_ctx, + handle, + firstjob, + numjobs, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - 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); + 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); - for (i=0; i<returned; i++) { - if (!smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumJobs(cli, mem_ctx, + handle, + firstjob, + numjobs, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - *info=inf; - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinterDrivers **********************************************************************/ -static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_1 **jobs) +WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *server, + const char *environment, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_DriverInfo **info) { - uint32 i; - - 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); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - for (i = 0; i < num_jobs; i++) { - if (!smb_io_job_info_1("", buffer, &((*jobs)[i]), 0)) { - return False; - } + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - return True; -} - -/********************************************************************** -**********************************************************************/ - -static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_2 **jobs) -{ - uint32 i; + status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx, + server, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - 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); + 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); - for (i = 0; i < num_jobs; i++) { - if (!smb_io_job_info_2("", buffer, &((*jobs)[i]), 0)) { - return False; - } + status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx, + server, + environment, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - return True; + return werror; } /********************************************************************** + convencience wrapper around rpccli_spoolss_EnumPrinters **********************************************************************/ -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) +WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *server, + uint32_t level, + uint32_t offered, + uint32_t *count, + union spoolss_PrinterInfo **info) { - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERS in; - SPOOL_R_ENUMPRINTERS out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinters, - spoolss_io_r_enumprinters, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered ); + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinters, - spoolss_io_r_enumprinters, - WERR_GENERAL_FAILURE ); + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); } - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 0: - if (!decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0)) { - return WERR_GENERAL_FAILURE; - } - break; - case 1: - if (!decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 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; -} - -/********************************************************************** -**********************************************************************/ - -WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32 level, const char *env, - uint32 *num_drivers, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDRIVERS in; - SPOOL_R_ENUMPRINTERDRIVERS 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; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinterdrivers( &in, server, env, level, - &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterdrivers, - spoolss_io_r_enumprinterdrivers, - WERR_GENERAL_FAILURE ); + status = rpccli_spoolss_EnumPrinters(cli, mem_ctx, + flags, + server, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_enumprinterdrivers( &in, server, env, level, - &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumprinterdrivers, - spoolss_io_r_enumprinterdrivers, - WERR_GENERAL_FAILURE ); - } - - *num_drivers = out.returned; + 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); - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - if ( out.returned ) { - - switch (level) { - case 1: - if (!decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } + status = rpccli_spoolss_EnumPrinters(cli, mem_ctx, + flags, + server, + level, + (offered > 0) ? &buffer : NULL, + offered, + count, + info, + &needed, + &werror); } - return out.status; + return werror; } -/********************************************************************** -**********************************************************************/ - -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) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMJOBS in; - SPOOL_R_ENUMJOBS out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - 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_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumjobs, - spoolss_io_r_enumjobs, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - 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_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS, - in, out, - qbuf, rbuf, - spoolss_io_q_enumjobs, - spoolss_io_r_enumjobs, - WERR_GENERAL_FAILURE ); - } - - if (!W_ERROR_IS_OK(out.status)) - return out.status; - - switch(level) { - case 1: - if (!decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 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)); - return WERR_UNKNOWN_LEVEL; - } - - *returned = out.returned; - - return out.status; -} +/********************************************************************* + Decode various spoolss rpc's and info levels + ********************************************************************/ /********************************************************************** **********************************************************************/ |