1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00
samba-mirror/source3/rpc_client/cli_spoolss.c
Günther Deschner a2aa7d6d65 s3-spoolss: Make spoolss client os_major,os_minor and os_build configurable.
Similar to spoolss server options, make the client advertised OS version
values configurable to allow overriding the defaults provided to the print server.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13597

Signed-off-by: Guenther Deschner <gd@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
2018-09-08 01:43:27 +02:00

1007 lines
25 KiB
C

/*
Unix SMB/CIFS implementation.
RPC pipe client
Copyright (C) Gerald Carter 2001-2005,
Copyright (C) Tim Potter 2000-2002,
Copyright (C) Andrew Tridgell 1994-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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "rpc_client/rpc_client.h"
#include "../librpc/gen_ndr/ndr_spoolss_c.h"
#include "rpc_client/cli_spoolss.h"
#include "auth/gensec/gensec.h"
#include "auth/credentials/credentials.h"
#include "rpc_client/init_spoolss.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;
struct spoolss_UserLevelCtr userlevel_ctr;
struct spoolss_UserLevel1 level1;
struct dcerpc_binding_handle *b = cli->binding_handle;
struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx);
ZERO_STRUCT(devmode_ctr);
werror = spoolss_init_spoolss_UserLevel1(mem_ctx,
cli_credentials_get_username(creds),
&level1);
if (!W_ERROR_IS_OK(werror)) {
return werror;
}
userlevel_ctr.level = 1;
userlevel_ctr.user_info.level1 = &level1;
status = dcerpc_spoolss_OpenPrinterEx(b, mem_ctx,
printername,
NULL,
devmode_ctr,
access_desired,
userlevel_ctr,
handle,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
if (!W_ERROR_IS_OK(werror)) {
return werror;
}
return WERR_OK;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_GetPrinterDriver
**********************************************************************/
WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
const char *architecture,
uint32_t level,
uint32_t offered,
union spoolss_DriverInfo *info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx,
handle,
architecture,
level,
(offered > 0) ? &buffer : NULL,
offered,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx,
handle,
architecture,
level,
&buffer,
offered,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
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;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_GetPrinterDriver2(b, 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 (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx,
handle,
architecture,
level,
&buffer,
offered,
client_major_version,
client_minor_version,
info,
&needed,
server_major_version,
server_minor_version,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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;
struct dcerpc_binding_handle *b = cli->binding_handle;
struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx);
ZERO_STRUCT(devmode_ctr);
ZERO_STRUCT(secdesc_ctr);
result = spoolss_init_spoolss_UserLevel1(mem_ctx,
cli_credentials_get_username(creds),
&level1);
if (!W_ERROR_IS_OK(result)) {
return result;
}
userlevel_ctr.level = 1;
userlevel_ctr.user_info.level1 = &level1;
status = dcerpc_spoolss_AddPrinterEx(b, mem_ctx,
cli->srv_name_slash,
info_ctr,
&devmode_ctr,
&secdesc_ctr,
&userlevel_ctr,
&handle,
&result);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_GetPrinter(b, mem_ctx,
handle,
level,
(offered > 0) ? &buffer : NULL,
offered,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_GetPrinter(b, mem_ctx,
handle,
level,
&buffer,
offered,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_GetJob
**********************************************************************/
WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
uint32_t job_id,
uint32_t level,
uint32_t offered,
union spoolss_JobInfo *info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_GetJob(b, mem_ctx,
handle,
job_id,
level,
(offered > 0) ? &buffer : NULL,
offered,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_GetJob(b, mem_ctx,
handle,
job_id,
level,
&buffer,
offered,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumForms
**********************************************************************/
WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
uint32_t level,
uint32_t offered,
uint32_t *count,
union spoolss_FormInfo **info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumForms(b, mem_ctx,
handle,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumForms(b, mem_ctx,
handle,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumPrintProcessors
**********************************************************************/
WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *servername,
const char *environment,
uint32_t level,
uint32_t offered,
uint32_t *count,
union spoolss_PrintProcessorInfo **info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx,
servername,
environment,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx,
servername,
environment,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumPrintProcessorDataTypes
**********************************************************************/
WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *servername,
const char *print_processor_name,
uint32_t level,
uint32_t offered,
uint32_t *count,
union spoolss_PrintProcDataTypesInfo **info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumPrintProcessorDataTypes(b, mem_ctx,
servername,
print_processor_name,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumPrintProcessorDataTypes(b, mem_ctx,
servername,
print_processor_name,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumPorts
**********************************************************************/
WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *servername,
uint32_t level,
uint32_t offered,
uint32_t *count,
union spoolss_PortInfo **info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumPorts(b, mem_ctx,
servername,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumPorts(b, mem_ctx,
servername,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumMonitors
**********************************************************************/
WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *servername,
uint32_t level,
uint32_t offered,
uint32_t *count,
union spoolss_MonitorInfo **info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumMonitors(b, mem_ctx,
servername,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumMonitors(b, mem_ctx,
servername,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumJobs
**********************************************************************/
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)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumJobs(b, mem_ctx,
handle,
firstjob,
numjobs,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumJobs(b, mem_ctx,
handle,
firstjob,
numjobs,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumPrinterDrivers
**********************************************************************/
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)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
server,
environment,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
server,
environment,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumPrinters
**********************************************************************/
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)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
DATA_BLOB buffer;
struct dcerpc_binding_handle *b = cli->binding_handle;
if (offered > 0) {
buffer = data_blob_talloc_zero(mem_ctx, offered);
W_ERROR_HAVE_NO_MEMORY(buffer.data);
}
status = dcerpc_spoolss_EnumPrinters(b, mem_ctx,
flags,
server,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
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 = dcerpc_spoolss_EnumPrinters(b, mem_ctx,
flags,
server,
level,
(offered > 0) ? &buffer : NULL,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_GetPrinterData
**********************************************************************/
WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
const char *value_name,
uint32_t offered,
enum winreg_Type *type,
uint32_t *needed_p,
uint8_t **data_p)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
uint8_t *data;
struct dcerpc_binding_handle *b = cli->binding_handle;
data = talloc_zero_array(mem_ctx, uint8_t, offered);
W_ERROR_HAVE_NO_MEMORY(data);
status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
handle,
value_name,
type,
data,
offered,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
offered = needed;
data = talloc_zero_array(mem_ctx, uint8_t, offered);
W_ERROR_HAVE_NO_MEMORY(data);
status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
handle,
value_name,
type,
data,
offered,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
*data_p = data;
*needed_p = needed;
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumPrinterKey
**********************************************************************/
WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
const char *key_name,
const char ***key_buffer,
uint32_t offered)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
union spoolss_KeyNames _key_buffer;
uint32_t _ndr_size;
struct dcerpc_binding_handle *b = cli->binding_handle;
status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx,
handle,
key_name,
&_ndr_size,
&_key_buffer,
offered,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
offered = needed;
status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx,
handle,
key_name,
&_ndr_size,
&_key_buffer,
offered,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
*key_buffer = _key_buffer.string_array;
return werror;
}
/**********************************************************************
convencience wrapper around rpccli_spoolss_EnumPrinterDataEx
**********************************************************************/
WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
const char *key_name,
uint32_t offered,
uint32_t *count,
struct spoolss_PrinterEnumValues **info)
{
NTSTATUS status;
WERROR werror;
uint32_t needed;
struct dcerpc_binding_handle *b = cli->binding_handle;
status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx,
handle,
key_name,
offered,
count,
info,
&needed,
&werror);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
offered = needed;
status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx,
handle,
key_name,
offered,
count,
info,
&needed,
&werror);
}
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
return werror;
}