From 6b4cac2c00bd77c34bfe47f35729a60782b8c9c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 21 Feb 2005 13:54:06 +0000 Subject: [PATCH] r5489: hide handwritten pull/push/print code from the caller for the spoolss_Enum* functions metze (This used to be commit bfcc86e706cf32672323eda939e5def6694509a8) --- source4/include/structs.h | 10 +- source4/librpc/idl/spoolss.idl | 46 +- source4/librpc/ndr/ndr_spoolss_buf.c | 832 ++++++++++++++++++++++++---- source4/rpc_server/spoolss/dcesrv_spoolss.c | 214 +++---- source4/torture/rpc/spoolss.c | 125 +---- 5 files changed, 857 insertions(+), 370 deletions(-) rewrite source4/librpc/ndr/ndr_spoolss_buf.c (67%) diff --git a/source4/include/structs.h b/source4/include/structs.h index be52755d798..2aa70b18559 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -23,11 +23,11 @@ "scope is only this definition or declaration" warning */ -union spoolss_PrinterInfo; -union spoolss_FormInfo; -union spoolss_JobInfo; -union spoolss_DriverInfo; -union spoolss_PortInfo; +struct spoolss_EnumPrinters; +struct spoolss_EnumForms; +struct spoolss_EnumJobs; +struct spoolss_EnumPrinterDrivers; +struct spoolss_EnumPorts; struct MULTI_QI; struct COSERVERINFO; diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl index a14f9dd8248..0ac941190b2 100644 --- a/source4/librpc/idl/spoolss.idl +++ b/source4/librpc/idl/spoolss.idl @@ -174,22 +174,24 @@ /******************/ /* Function: 0x00 */ - WERROR spoolss_EnumPrinters( - [in] uint32 flags, - [in] unistr *server, - [in] uint32 level, - [in,out] DATA_BLOB *buffer, + [noprint,nopull,nopush] WERROR spoolss_EnumPrinters( + [in] uint32 flags, + [in] unistr *server, + [in] uint32 level, + [in] DATA_BLOB *buffer, + /* [out,subcontext(4),switch_is(level)] spoolss_PrinterInfo *info[count],*/ + [out,subcontext(4),switch_is(level)] spoolss_PrinterInfo **info, [in,out,ref] uint32 *buf_size, - [out] uint32 count + [out] uint32 count ); /******************/ /* Function: 0x01 */ WERROR spoolss_OpenPrinter( - [in] unistr *server, - [in] unistr *printer, - [in] DATA_BLOB *buffer, - [in] uint32 access_mask, + [in] unistr *server, + [in] unistr *printer, + [in] DATA_BLOB *buffer, + [in] uint32 access_mask, [out,ref] policy_handle *handle ); @@ -235,12 +237,14 @@ /******************/ /* Function: 0x04 */ - WERROR spoolss_EnumJobs( + [noprint,nopull,nopush] WERROR spoolss_EnumJobs( [in,ref] policy_handle *handle, [in] uint32 firstjob, [in] uint32 numjobs, [in] uint32 level, - [in,out] DATA_BLOB *buffer, + [in] DATA_BLOB *buffer, + /* [out,subcontext(4),switch_is(level)] spoolss_JobInfo *info[count],*/ + [out,subcontext(4),switch_is(level)] spoolss_JobInfo **info, [in,out,ref] uint32 *buf_size, [out] uint32 count ); @@ -311,11 +315,13 @@ /******************/ /* Function: 0x0a */ - WERROR spoolss_EnumPrinterDrivers( + [noprint,nopull,nopush] WERROR spoolss_EnumPrinterDrivers( [in] unistr *server, [in] unistr *environment, [in] uint32 level, - [in,out] DATA_BLOB *buffer, + [in] DATA_BLOB *buffer, + /* [out,subcontext(4),switch_is(level)] spoolss_DriverInfo *info[count],*/ + [out,subcontext(4),switch_is(level)] spoolss_DriverInfo **info, [in,out,ref] uint32 *buf_size, [out] uint32 count ); @@ -514,10 +520,12 @@ /******************/ /* Function: 0x22 */ - WERROR spoolss_EnumForms( + [noprint,nopull,nopush] WERROR spoolss_EnumForms( [in,ref] policy_handle *handle, [in] uint32 level, - [in,out] DATA_BLOB *buffer, + [in] DATA_BLOB *buffer, + /* [out,subcontext(4),switch_is(level)] spoolss_FormInfo *info[count],*/ + [out,subcontext(4),switch_is(level)] spoolss_FormInfo **info, [in,out,ref] uint32 *buf_size, [out] uint32 count ); @@ -541,10 +549,12 @@ /******************/ /* Function: 0x23 */ - WERROR spoolss_EnumPorts( + [noprint,nopull,nopush] WERROR spoolss_EnumPorts( [in] unistr *servername, [in] uint32 level, - [in,out] DATA_BLOB *buffer, + [in] DATA_BLOB *buffer, + /* [out,subcontext(4),switch_is(level)] spoolss_PortInfo *info[count], */ + [out,subcontext(4),switch_is(level)] spoolss_PortInfo **info, [in,out,ref] uint32 *buf_size, [out] uint32 count ); diff --git a/source4/librpc/ndr/ndr_spoolss_buf.c b/source4/librpc/ndr/ndr_spoolss_buf.c dissimilarity index 67% index e481503ccf8..0dcae6fad71 100644 --- a/source4/librpc/ndr/ndr_spoolss_buf.c +++ b/source4/librpc/ndr/ndr_spoolss_buf.c @@ -1,121 +1,711 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling spoolss subcontext buffer structures - - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Tim Potter 2003 - - 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 - (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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#include "includes.h" -#include "librpc/gen_ndr/ndr_spoolss.h" - -NTSTATUS pull_spoolss_PrinterInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_PrinterInfo **info) -{ - int i; - struct ndr_pull *ndr; - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - NDR_ALLOC_N(ndr, *info, count); - for (i=0;idata += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_PrinterInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); - } - return NT_STATUS_OK; -} - -NTSTATUS pull_spoolss_FormInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_FormInfo **info) -{ - int i; - struct ndr_pull *ndr; - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - NDR_ALLOC_N(ndr, *info, count); - for (i=0;idata += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_FormInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); - } - return NT_STATUS_OK; -} - -NTSTATUS pull_spoolss_JobInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_JobInfo **info) -{ - int i; - struct ndr_pull *ndr; - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - NDR_ALLOC_N(ndr, *info, count); - for (i=0;idata += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_JobInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); - } - return NT_STATUS_OK; -} - -NTSTATUS pull_spoolss_DriverInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_DriverInfo **info) -{ - int i; - struct ndr_pull *ndr; - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - NDR_ALLOC_N(ndr, *info, count); - for (i=0;idata += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_DriverInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); - } - return NT_STATUS_OK; -} - -NTSTATUS pull_spoolss_PortInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_PortInfo **info) -{ - int i; - struct ndr_pull *ndr; - ndr = ndr_pull_init_blob(blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - NDR_ALLOC_N(ndr, *info, count); - for (i=0;idata += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_PortInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); - } - return NT_STATUS_OK; -} +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling spoolss subcontext buffer structures + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Tim Potter 2003 + + 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 + (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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" +#include "librpc/gen_ndr/ndr_spoolss.h" + +#define NDR_SPOOLSS_PUSH_ENUM_OUT(fn,type) do { \ + DATA_BLOB buffer;\ + if (r->out.info) {\ + int i;\ + struct ndr_push *ndr2;\ +\ + ndr2 = ndr_push_init_ctx(ndr);\ + if (!ndr2) {\ + return NT_STATUS_NO_MEMORY;\ + }\ +\ + for (i=0;iout.count;i++) {\ + ndr2->data += ndr2->offset;\ + ndr2->offset = 0;\ + NDR_CHECK(ndr_push_##type(ndr2, NDR_SCALARS|NDR_BUFFERS, r->in.level, &(*r->out.info)[i]));\ + }\ + if (*r->in.buf_size >= ndr->offset) {\ + buffer = data_blob_const(ndr2->data, ndr2->offset);\ + } else {\ + r->out.info = NULL;\ + r->out.count = 0;\ + r->out.result = WERR_INSUFFICIENT_BUFFER;\ + }\ + *r->out.buf_size = ndr2->offset;\ + }\ + NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info));\ + if (r->out.info) {\ + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, buffer));\ + }\ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.buf_size));\ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.count));\ + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));\ +} while(0) + +#define NDR_SPOOLSS_PULL_ENUM_OUT(fn,type) do { \ + int i;\ + DATA_BLOB buffer;\ + struct ndr_pull *ndr2;\ +\ + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_info));\ + if (_ptr_info) {\ + NDR_ALLOC(ndr, r->out.info);\ + } else {\ + r->out.info = NULL;\ + }\ + if (r->out.info) {\ + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, &buffer));\ + *r->out.info = NULL;\ + }\ + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {\ + NDR_ALLOC(ndr, r->out.buf_size);\ + }\ + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.buf_size));\ + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->out.count));\ + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));\ +\ + if (r->out.info == NULL && r->out.count) {\ + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,\ + #fn ": r->out.count[%d] but r->out.info == NULL\n",\ + r->out.count);\ + }\ +\ + if (r->out.info && r->out.count) {\ + ndr2 = ndr_pull_init_blob(&buffer, ndr);\ + if (!ndr2) return NT_STATUS_NO_MEMORY;\ + NDR_ALLOC_N(ndr2, *r->out.info, r->out.count);\ + for (i=0;iout.count;i++) {\ + ndr2->data += ndr2->offset;\ + ndr2->offset = 0;\ + NDR_CHECK(ndr_pull_##type(ndr2, NDR_SCALARS|NDR_BUFFERS, r->in.level, &(*r->out.info)[i]));\ + }\ + }\ +} while(0) + +#define NDR_SPOOLSS_PRINT_ENUM_OUT(fn,type) do { \ + ndr_print_struct(ndr, "out", #fn);\ + ndr->depth++;\ + ndr_print_ptr(ndr, "info", r->out.info);\ + ndr->depth++;\ + if (r->out.info) {\ + int i;\ + ndr->print(ndr, "%s: ARRAY(%d)", "info", r->out.count);\ + ndr->depth++;\ + for (i=0;iout.count;i++) {\ + char *idx=NULL;\ + asprintf(&idx, "[%d]", i);\ + if (idx) {\ + ndr_print_##type(ndr, idx, r->in.level, &((*r->out.info)[i]));\ + free(idx);\ + }\ + }\ + ndr->depth--;\ + }\ + ndr->depth--;\ + ndr_print_ptr(ndr, "buf_size", r->out.buf_size);\ + ndr->depth++;\ + ndr_print_uint32(ndr, "buf_size", *r->out.buf_size);\ + ndr->depth--;\ + ndr_print_uint32(ndr, "count", r->out.count);\ + ndr_print_WERROR(ndr, "result", r->out.result);\ + ndr->depth--;\ +} while(0) + +/* + spoolss_EnumPrinters +*/ +NTSTATUS ndr_push_spoolss_EnumPrinters(struct ndr_push *ndr, int flags, struct spoolss_EnumPrinters *r) +{ + if (!(flags & NDR_IN)) goto ndr_out; + + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.flags)); + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.server)); + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.server) { + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.server)); + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.level)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer)); + if (r->in.buffer) { + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buffer)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buf_size)); + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PUSH_ENUM_OUT(spoolss_EnumPrinters,spoolss_PrinterInfo); + + done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_spoolss_EnumPrinters(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinters *r) +{ + uint32_t _ptr_server; + uint32_t _ptr_buffer; + uint32_t _ptr_info; + if (!(flags & NDR_IN)) goto ndr_out; + + ZERO_STRUCT(r->out); + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.flags)); + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_server)); + if (_ptr_server) { + NDR_ALLOC(ndr, r->in.server); + } else { + r->in.server = NULL; + } + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.server) { + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.server)); + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.level)); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_buffer)); + if (_ptr_buffer) { + NDR_ALLOC(ndr, r->in.buffer); + } else { + r->in.buffer = NULL; + } + if (r->in.buffer) { + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buffer)); + } + NDR_ALLOC(ndr, r->in.buf_size); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buf_size)); + NDR_ALLOC(ndr, r->out.buf_size); + *r->out.buf_size = *r->in.buf_size; + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PULL_ENUM_OUT(spoolss_EnumPrinters,spoolss_PrinterInfo); + + done: + + return NT_STATUS_OK; +} + +void ndr_print_spoolss_EnumPrinters(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumPrinters *r) +{ + ndr_print_struct(ndr, name, "spoolss_EnumPrinters"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "spoolss_EnumPrinters"); + ndr->depth++; + ndr_print_uint32(ndr, "flags", r->in.flags); + ndr_print_ptr(ndr, "server", r->in.server); + ndr->depth++; + if (r->in.server) { + ndr_print_string(ndr, "server", r->in.server); + } + ndr->depth--; + ndr_print_uint32(ndr, "level", r->in.level); + ndr_print_ptr(ndr, "buffer", r->in.buffer); + ndr->depth++; + if (r->in.buffer) { + ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer); + } + ndr->depth--; + ndr_print_ptr(ndr, "buf_size", r->in.buf_size); + ndr->depth++; + ndr_print_uint32(ndr, "buf_size", *r->in.buf_size); + ndr->depth--; + ndr->depth--; + } + if (flags & NDR_OUT) { + NDR_SPOOLSS_PRINT_ENUM_OUT(spoolss_EnumPrinters,spoolss_PrinterInfo); + } + ndr->depth--; +} + +/* + spoolss_EnumJobs +*/ +NTSTATUS ndr_push_spoolss_EnumJobs(struct ndr_push *ndr, int flags, struct spoolss_EnumJobs *r) +{ + if (!(flags & NDR_IN)) goto ndr_out; + + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.firstjob)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.numjobs)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.level)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer)); + if (r->in.buffer) { + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buffer)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buf_size)); + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PUSH_ENUM_OUT(spoolss_EnumJobs,spoolss_JobInfo); + + done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_spoolss_EnumJobs(struct ndr_pull *ndr, int flags, struct spoolss_EnumJobs *r) +{ + uint32_t _ptr_buffer; + uint32_t _ptr_info; + if (!(flags & NDR_IN)) goto ndr_out; + + ZERO_STRUCT(r->out); + + NDR_ALLOC(ndr, r->in.handle); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.firstjob)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.numjobs)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.level)); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_buffer)); + if (_ptr_buffer) { + NDR_ALLOC(ndr, r->in.buffer); + } else { + r->in.buffer = NULL; + } + if (r->in.buffer) { + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buffer)); + } + NDR_ALLOC(ndr, r->in.buf_size); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buf_size)); + NDR_ALLOC(ndr, r->out.buf_size); + *r->out.buf_size = *r->in.buf_size; + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PULL_ENUM_OUT(spoolss_EnumJobs,spoolss_JobInfo); + + done: + + return NT_STATUS_OK; +} + +void ndr_print_spoolss_EnumJobs(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumJobs *r) +{ + ndr_print_struct(ndr, name, "spoolss_EnumJobs"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "spoolss_EnumJobs"); + ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_uint32(ndr, "firstjob", r->in.firstjob); + ndr_print_uint32(ndr, "numjobs", r->in.numjobs); + ndr_print_uint32(ndr, "level", r->in.level); + ndr_print_ptr(ndr, "buffer", r->in.buffer); + ndr->depth++; + if (r->in.buffer) { + ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer); + } + ndr->depth--; + ndr_print_ptr(ndr, "buf_size", r->in.buf_size); + ndr->depth++; + ndr_print_uint32(ndr, "buf_size", *r->in.buf_size); + ndr->depth--; + ndr->depth--; + } + if (flags & NDR_OUT) { + NDR_SPOOLSS_PRINT_ENUM_OUT(spoolss_EnumJobs,spoolss_JobInfo); + } + ndr->depth--; +} + +/* + spoolss_EnumPrinterDrivers +*/ +NTSTATUS ndr_push_spoolss_EnumPrinterDrivers(struct ndr_push *ndr, int flags, struct spoolss_EnumPrinterDrivers *r) +{ + if (!(flags & NDR_IN)) goto ndr_out; + + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.server)); + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.server) { + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.server)); + } + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.environment)); + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.environment) { + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.environment)); + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.level)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer)); + if (r->in.buffer) { + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buffer)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buf_size)); + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PUSH_ENUM_OUT(spoolss_EnumPrinterDrivers,spoolss_DriverInfo); + + done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_spoolss_EnumPrinterDrivers(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDrivers *r) +{ + uint32_t _ptr_server; + uint32_t _ptr_environment; + uint32_t _ptr_buffer; + uint32_t _ptr_info; + if (!(flags & NDR_IN)) goto ndr_out; + + ZERO_STRUCT(r->out); + + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_server)); + if (_ptr_server) { + NDR_ALLOC(ndr, r->in.server); + } else { + r->in.server = NULL; + } + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.server) { + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.server)); + } + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_environment)); + if (_ptr_environment) { + NDR_ALLOC(ndr, r->in.environment); + } else { + r->in.environment = NULL; + } + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.environment) { + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.environment)); + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.level)); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_buffer)); + if (_ptr_buffer) { + NDR_ALLOC(ndr, r->in.buffer); + } else { + r->in.buffer = NULL; + } + if (r->in.buffer) { + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buffer)); + } + NDR_ALLOC(ndr, r->in.buf_size); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buf_size)); + NDR_ALLOC(ndr, r->out.buf_size); + *r->out.buf_size = *r->in.buf_size; + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PULL_ENUM_OUT(spoolss_EnumPrinterDrivers,spoolss_DriverInfo); + + done: + + return NT_STATUS_OK; +} + +void ndr_print_spoolss_EnumPrinterDrivers(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumPrinterDrivers *r) +{ + ndr_print_struct(ndr, name, "spoolss_EnumPrinterDrivers"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "spoolss_EnumPrinterDrivers"); + ndr->depth++; + ndr_print_ptr(ndr, "server", r->in.server); + ndr->depth++; + if (r->in.server) { + ndr_print_string(ndr, "server", r->in.server); + } + ndr->depth--; + ndr_print_ptr(ndr, "environment", r->in.environment); + ndr->depth++; + if (r->in.environment) { + ndr_print_string(ndr, "environment", r->in.environment); + } + ndr->depth--; + ndr_print_uint32(ndr, "level", r->in.level); + ndr_print_ptr(ndr, "buffer", r->in.buffer); + ndr->depth++; + if (r->in.buffer) { + ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer); + } + ndr->depth--; + ndr_print_ptr(ndr, "buf_size", r->in.buf_size); + ndr->depth++; + ndr_print_uint32(ndr, "buf_size", *r->in.buf_size); + ndr->depth--; + ndr->depth--; + } + if (flags & NDR_OUT) { + NDR_SPOOLSS_PRINT_ENUM_OUT(spoolss_EnumPrinterDrivers,spoolss_DriverInfo); + } + ndr->depth--; +} + +/* + spoolss_EnumForms +*/ +NTSTATUS ndr_push_spoolss_EnumForms(struct ndr_push *ndr, int flags, struct spoolss_EnumForms *r) +{ + if (!(flags & NDR_IN)) goto ndr_out; + + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.level)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer)); + if (r->in.buffer) { + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buffer)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buf_size)); + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PUSH_ENUM_OUT(spoolss_EnumForms,spoolss_FormInfo); + + done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_spoolss_EnumForms(struct ndr_pull *ndr, int flags, struct spoolss_EnumForms *r) +{ + uint32_t _ptr_buffer; + uint32_t _ptr_info; + if (!(flags & NDR_IN)) goto ndr_out; + + ZERO_STRUCT(r->out); + + NDR_ALLOC(ndr, r->in.handle); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.level)); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_buffer)); + if (_ptr_buffer) { + NDR_ALLOC(ndr, r->in.buffer); + } else { + r->in.buffer = NULL; + } + if (r->in.buffer) { + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buffer)); + } + NDR_ALLOC(ndr, r->in.buf_size); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buf_size)); + NDR_ALLOC(ndr, r->out.buf_size); + *r->out.buf_size = *r->in.buf_size; + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PULL_ENUM_OUT(spoolss_EnumForms,spoolss_FormInfo); + + done: + + return NT_STATUS_OK; +} + +void ndr_print_spoolss_EnumForms(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumForms *r) +{ + ndr_print_struct(ndr, name, "spoolss_EnumForms"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "spoolss_EnumForms"); + ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_uint32(ndr, "level", r->in.level); + ndr_print_ptr(ndr, "buffer", r->in.buffer); + ndr->depth++; + if (r->in.buffer) { + ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer); + } + ndr->depth--; + ndr_print_ptr(ndr, "buf_size", r->in.buf_size); + ndr->depth++; + ndr_print_uint32(ndr, "buf_size", *r->in.buf_size); + ndr->depth--; + ndr->depth--; + } + if (flags & NDR_OUT) { + NDR_SPOOLSS_PRINT_ENUM_OUT(spoolss_EnumForms,spoolss_FormInfo); + } + ndr->depth--; +} + +/* + spoolss_EnumPorts +*/ +NTSTATUS ndr_push_spoolss_EnumPorts(struct ndr_push *ndr, int flags, struct spoolss_EnumPorts *r) +{ + if (!(flags & NDR_IN)) goto ndr_out; + + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.servername)); + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.servername) { + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername)); + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.level)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.buffer)); + if (r->in.buffer) { + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buffer)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.buf_size)); + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PUSH_ENUM_OUT(spoolss_EnumPorts,spoolss_PortInfo); + + done: + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_spoolss_EnumPorts(struct ndr_pull *ndr, int flags, struct spoolss_EnumPorts *r) +{ + uint32_t _ptr_servername; + uint32_t _ptr_buffer; + uint32_t _ptr_info; + if (!(flags & NDR_IN)) goto ndr_out; + + ZERO_STRUCT(r->out); + + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_servername)); + if (_ptr_servername) { + NDR_ALLOC(ndr, r->in.servername); + } else { + r->in.servername = NULL; + } + ndr->flags = _flags_save_string; + } + { uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); + if (r->in.servername) { + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.servername)); + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.level)); + NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_buffer)); + if (_ptr_buffer) { + NDR_ALLOC(ndr, r->in.buffer); + } else { + r->in.buffer = NULL; + } + if (r->in.buffer) { + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buffer)); + } + NDR_ALLOC(ndr, r->in.buf_size); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.buf_size)); + NDR_ALLOC(ndr, r->out.buf_size); + *r->out.buf_size = *r->in.buf_size; + ndr_out: + if (!(flags & NDR_OUT)) goto done; + + NDR_SPOOLSS_PULL_ENUM_OUT(spoolss_EnumPorts,spoolss_PortInfo); + + done: + + return NT_STATUS_OK; +} + +void ndr_print_spoolss_EnumPorts(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumPorts *r) +{ + ndr_print_struct(ndr, name, "spoolss_EnumPorts"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "spoolss_EnumPorts"); + ndr->depth++; + ndr_print_ptr(ndr, "servername", r->in.servername); + ndr->depth++; + if (r->in.servername) { + ndr_print_string(ndr, "servername", r->in.servername); + } + ndr->depth--; + ndr_print_uint32(ndr, "level", r->in.level); + ndr_print_ptr(ndr, "buffer", r->in.buffer); + ndr->depth++; + if (r->in.buffer) { + ndr_print_DATA_BLOB(ndr, "buffer", *r->in.buffer); + } + ndr->depth--; + ndr_print_ptr(ndr, "buf_size", r->in.buf_size); + ndr->depth++; + ndr_print_uint32(ndr, "buf_size", *r->in.buf_size); + ndr->depth--; + ndr->depth--; + } + if (flags & NDR_OUT) { + NDR_SPOOLSS_PRINT_ENUM_OUT(spoolss_EnumPorts,spoolss_PortInfo); + } + ndr->depth--; +} diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index 8bb6a5c60fa..470c9e2674d 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -26,163 +26,121 @@ #include "rpc_server/common/common.h" #include "rpc_server/spoolss/dcesrv_spoolss.h" -static WERROR spoolss_EnumPrinters1(TALLOC_CTX *mem_ctx, - struct ldb_message **msgs, int num_msgs, - struct ndr_push *ndr) +/* + spoolss_EnumPrinters +*/ +static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_EnumPrinters *r) { - struct spoolss_PrinterInfo1 *info; + void *spoolss_ctx; + struct ldb_message **msgs; + int count; int i; + union spoolss_PrinterInfo *info; - info = talloc_array(mem_ctx, struct spoolss_PrinterInfo1, num_msgs); - - if (!info) - return WERR_NOMEM; + r->out.info = NULL; + *r->out.buf_size = 0; + r->out.count = 0; - for (i = 0; i < num_msgs; i++) { - info[i].flags = samdb_result_uint(msgs[i], "flags", 0); - info[i].name = samdb_result_string(msgs[i], "name", ""); - info[i].description = samdb_result_string(msgs[i], "description", ""); - info[i].comment = samdb_result_string(msgs[i], "comment", ""); - } + spoolss_ctx = spoolssdb_connect(); + W_ERROR_HAVE_NO_MEMORY(spoolss_ctx); - ndr_push_array(ndr, NDR_SCALARS|NDR_BUFFERS, info, - sizeof(struct spoolss_PrinterInfo1), num_msgs, - (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo1); + count = spoolssdb_search(spoolss_ctx, mem_ctx, NULL, &msgs, NULL, + "(&(objectclass=printer))"); + spoolssdb_close(spoolss_ctx); - return WERR_OK; -} + if (count == 0) return WERR_OK; + if (count < 0) return WERR_GENERAL_FAILURE; -static WERROR spoolss_EnumPrinters2(TALLOC_CTX *mem_ctx, - struct ldb_message **msgs, int num_msgs, - struct ndr_push *ndr) -{ - struct spoolss_PrinterInfo2 *info; - int i; + info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count); + W_ERROR_HAVE_NO_MEMORY(info); - info = talloc_array(mem_ctx, struct spoolss_PrinterInfo2, num_msgs); + switch(r->in.level) { + case 1: + for (i = 0; i < count; i++) { + info[i].info1.flags = samdb_result_uint(msgs[i], "flags", 0); - if (!info) - return WERR_NOMEM; + info[i].info1.name = samdb_result_string(msgs[i], "name", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info1.name); - for (i = 0; i < num_msgs; i++) { - info[i].servername = samdb_result_string(msgs[i], "servername", ""); - info[i].printername = samdb_result_string(msgs[i], "printername", ""); - info[i].sharename = samdb_result_string(msgs[i], "sharename", ""); - info[i].portname = samdb_result_string(msgs[i], "portname", ""); - info[i].drivername = samdb_result_string(msgs[i], "drivername", ""); - info[i].comment = samdb_result_string(msgs[i], "comment", ""); - info[i].location = samdb_result_string(msgs[i], "location", ""); - /* DEVICEMODE - eek! */ - info[i].sepfile = samdb_result_string(msgs[i], "sepfile", ""); - info[i].printprocessor = samdb_result_string(msgs[i], "printprocessor", ""); - info[i].datatype = samdb_result_string(msgs[i], "datatype", ""); - info[i].parameters = samdb_result_string(msgs[i], "parameters", ""); - /* SECURITY_DESCRIPTOR */ - info[i].attributes = samdb_result_uint(msgs[i], "attributes", 0); - info[i].priority = samdb_result_uint(msgs[i], "priority", 0); - info[i].defaultpriority = samdb_result_uint(msgs[i], "defaultpriority", 0); - info[i].starttime = samdb_result_uint(msgs[i], "starttime", 0); - info[i].untiltime = samdb_result_uint(msgs[i], "untiltime", 0); - info[i].status = samdb_result_uint(msgs[i], "status", 0); - info[i].cjobs = samdb_result_uint(msgs[i], "cjobs", 0); - info[i].averageppm = samdb_result_uint(msgs[i], "averageppm", 0); - } + info[i].info1.description = samdb_result_string(msgs[i], "description", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info1.description); - ndr_push_array(ndr, NDR_SCALARS|NDR_BUFFERS, info, - sizeof(struct spoolss_PrinterInfo2), num_msgs, - (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo2); + info[i].info1.comment = samdb_result_string(msgs[i], "comment", NULL); + } + return WERR_OK; + case 2: + for (i = 0; i < count; i++) { + info[i].info2.servername = samdb_result_string(msgs[i], "servername", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername); - return WERR_OK; -} + info[i].info2.printername = samdb_result_string(msgs[i], "printername", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername); -static WERROR spoolss_EnumPrinters5(TALLOC_CTX *mem_ctx, - struct ldb_message **msgs, int num_msgs, - struct ndr_push *ndr) -{ - struct spoolss_PrinterInfo5 *info; - int i; + info[i].info2.sharename = samdb_result_string(msgs[i], "sharename", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename); - info = talloc_array(mem_ctx, struct spoolss_PrinterInfo5, num_msgs); + info[i].info2.portname = samdb_result_string(msgs[i], "portname", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname); - if (!info) - return WERR_NOMEM; + info[i].info2.drivername = samdb_result_string(msgs[i], "drivername", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername); - for (i = 0; i < num_msgs; i++) { - info[i].printername = samdb_result_string(msgs[i], "name", ""); - info[i].portname = samdb_result_string(msgs[i], "port", ""); - info[i].attributes = samdb_result_uint(msgs[i], "attributes", 0); - info[i].device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0); - info[i].transmission_retry_timeout = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0); - } + info[i].info2.comment = samdb_result_string(msgs[i], "comment", NULL); - ndr_push_array(ndr, NDR_SCALARS|NDR_BUFFERS, info, - sizeof(struct spoolss_PrinterInfo5), num_msgs, - (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterInfo5); + info[i].info2.location = samdb_result_string(msgs[i], "location", NULL); - return WERR_OK; -} + info[i].info2.devmode = NULL; -/* - spoolss_EnumPrinters -*/ -static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct spoolss_EnumPrinters *r) -{ - struct ndr_push *ndr; - void *spoolss_ctx; - WERROR result; - struct ldb_message **msgs; - int ret; + info[i].info2.sepfile = samdb_result_string(msgs[i], "sepfile", NULL); - spoolss_ctx = spoolssdb_connect(); - if (spoolss_ctx == NULL) - return WERR_NOMEM; + info[i].info2.printprocessor = samdb_result_string(msgs[i], "printprocessor", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor); - ret = spoolssdb_search(spoolss_ctx, mem_ctx, NULL, &msgs, NULL, - "(&(objectclass=printer))"); - - ndr = ndr_push_init(); + info[i].info2.datatype = samdb_result_string(msgs[i], "datatype", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype); - r->out.count = 0; - *r->out.buf_size = 0; + info[i].info2.parameters = samdb_result_string(msgs[i], "parameters", NULL); - switch(r->in.level) { - case 1: - result = spoolss_EnumPrinters1(mem_ctx, msgs, ret, ndr); - break; - case 2: - result = spoolss_EnumPrinters2(mem_ctx, msgs, ret, ndr); - break; - case 5: - result = spoolss_EnumPrinters5(mem_ctx, msgs, ret, ndr); - break; - default: - r->out.buffer = NULL; - result = WERR_UNKNOWN_LEVEL; - goto done; - } + info[i].info2.secdesc = NULL; - if (*r->in.buf_size < ndr->offset) { - *r->out.buf_size = ndr->offset; - result = WERR_INSUFFICIENT_BUFFER; - goto done; - } + info[i].info2.attributes = samdb_result_uint(msgs[i], "attributes", 0); + info[i].info2.priority = samdb_result_uint(msgs[i], "priority", 0); + info[i].info2.defaultpriority = samdb_result_uint(msgs[i], "defaultpriority", 0); + info[i].info2.starttime = samdb_result_uint(msgs[i], "starttime", 0); + info[i].info2.untiltime = samdb_result_uint(msgs[i], "untiltime", 0); + info[i].info2.status = samdb_result_uint(msgs[i], "status", 0); + info[i].info2.cjobs = samdb_result_uint(msgs[i], "cjobs", 0); + info[i].info2.averageppm = samdb_result_uint(msgs[i], "averageppm", 0); + } + return WERR_OK; + case 4: + for (i = 0; i < count; i++) { + info[i].info4.printername = samdb_result_string(msgs[i], "printername", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername); - r->out.buffer = talloc(mem_ctx, DATA_BLOB); + info[i].info4.servername = samdb_result_string(msgs[i], "servername", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername); - if (!r->out.buffer) { - result = WERR_NOMEM; - goto done; - } + info[i].info4.attributes = samdb_result_uint(msgs[i], "attributes", 0); + } + return WERR_OK; + case 5: + for (i = 0; i < count; i++) { + info[i].info5.printername = samdb_result_string(msgs[i], "name", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername); - *r->out.buffer = data_blob_talloc(mem_ctx, ndr->data, ndr->offset); - *r->out.buf_size = ndr->offset; + info[i].info5.portname = samdb_result_string(msgs[i], "port", ""); + W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname); - done: - ndr_push_free(ndr); - spoolssdb_close(spoolss_ctx); + info[i].info5.attributes = samdb_result_uint(msgs[i], "attributes", 0); + info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0); + info[i].info5.transmission_retry_timeout = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0); + } + return WERR_OK; + } - return result; + return WERR_UNKNOWN_LEVEL; } diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index c11a004e335..8e4ea15677e 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -162,24 +162,16 @@ static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r); - if (!r.out.buffer) { + if (!r.out.info) { printf("No forms returned"); return False; } - status = pull_spoolss_FormInfoArray(r.out.buffer, mem_ctx, r.in.level, r.out.count, &info); - if (!NT_STATUS_IS_OK(status)) { - printf("EnumFormsArray parse failed - %s\n", nt_errstr(status)); - return False; - } - - for (j=0;j