diff options
-rw-r--r-- | source4/include/structs.h | 10 | ||||
-rw-r--r-- | source4/librpc/idl/spoolss.idl | 46 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss_buf.c | 730 | ||||
-rw-r--r-- | source4/rpc_server/spoolss/dcesrv_spoolss.c | 214 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss.c | 125 |
5 files changed, 806 insertions, 319 deletions
diff --git a/source4/include/structs.h b/source4/include/structs.h index be52755d79..2aa70b1855 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 a14f9dd824..0ac941190b 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 index e481503ccf..0dcae6fad7 100644 --- a/source4/librpc/ndr/ndr_spoolss_buf.c +++ b/source4/librpc/ndr/ndr_spoolss_buf.c @@ -25,97 +25,687 @@ #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) +#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;i<r->out.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;i<r->out.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;i<r->out.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) { - 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;i<count;i++) { - ndr->data += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_PrinterInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); + 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; } -NTSTATUS pull_spoolss_FormInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_FormInfo **info) +void ndr_print_spoolss_EnumPrinterDrivers(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumPrinterDrivers *r) { - 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;i<count;i++) { - ndr->data += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_FormInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); + 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 pull_spoolss_JobInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_JobInfo **info) +NTSTATUS ndr_pull_spoolss_EnumForms(struct ndr_pull *ndr, int flags, struct spoolss_EnumForms *r) { - 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;i<count;i++) { - ndr->data += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_JobInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); + 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; } -NTSTATUS pull_spoolss_DriverInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_DriverInfo **info) +void ndr_print_spoolss_EnumForms(struct ndr_print *ndr, const char *name, int flags, struct spoolss_EnumForms *r) { - 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;i<count;i++) { - ndr->data += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_DriverInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); + 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 pull_spoolss_PortInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32_t level, uint32_t count, - union spoolss_PortInfo **info) +NTSTATUS ndr_pull_spoolss_EnumPorts(struct ndr_pull *ndr, int flags, struct spoolss_EnumPorts *r) { - 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;i<count;i++) { - ndr->data += ndr->offset; - ndr->offset = 0; - NDR_CHECK(ndr_pull_spoolss_PortInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i])); + 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 8bb6a5c60f..470c9e2674 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 c11a004e33..8e4ea15677 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<r.out.count;j++) { - printf("Form %d\n", j); - NDR_PRINT_UNION_DEBUG(spoolss_FormInfo, r.in.level, &info[j]); - } + info = *r.out.info; - for (j = 0; j < r.out.count; j++) + for (j = 0; j < r.out.count; j++) { test_GetForm(p, mem_ctx, handle, info[j].info1.formname); + } } if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { @@ -298,8 +290,6 @@ static BOOL test_EnumPorts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size); - union spoolss_PortInfo *info; - int j; data_blob_clear(&blob); r.in.buffer = &blob; @@ -311,25 +301,10 @@ static BOOL test_EnumPorts(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) return False; } - if (!r.out.buffer) { + if (!r.out.info) { printf("No ports returned"); return False; } - - status = pull_spoolss_PortInfoArray(r.out.buffer, mem_ctx, - r.in.level, r.out.count, - &info); - if (!NT_STATUS_IS_OK(status)) { - printf("EnumPortArray parse failed - %s\n", - nt_errstr(status)); - return False; - } - - for (j=0;j<r.out.count;j++) { - printf("Port %d\n", j); - NDR_PRINT_UNION_DEBUG(spoolss_PortInfo, r.in.level, - &info[j]); - } } return True; @@ -433,31 +408,16 @@ static BOOL test_EnumJobs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r); - if (!r.out.buffer) { + if (!r.out.info) { printf("No jobs returned"); return True; } - status = pull_spoolss_JobInfoArray( - r.out.buffer, mem_ctx, r.in.level, r.out.count, - &info); - - if (!NT_STATUS_IS_OK(status)) { - printf("EnumJobsArray parse failed - %s\n", - nt_errstr(status)); - return False; - } - - for (j = 0; j < r.out.count; j++) { - printf("Job %d\n", j); - NDR_PRINT_UNION_DEBUG( - spoolss_JobInfo, r.in.level, &info[j]); - } + info = *r.out.info; for (j = 0; j < r.out.count; j++) { test_GetJob(p, mem_ctx, handle, info[j].info1.job_id); - test_SetJob( - p, mem_ctx, handle, info[j].info1.job_id, 1); + test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, 1); } } else if (!W_ERROR_IS_OK(r.out.result)) { @@ -697,7 +657,7 @@ static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = &handle; - printf("\nTesting OpenPrinter(\\\\%s)\n", r.in.server); + printf("\nTesting OpenPrinter(%s)\n", r.in.server); status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { @@ -858,21 +818,12 @@ static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) continue; } - if (!r.out.buffer) { + if (!r.out.info) { printf("No printers returned"); continue; } - status = pull_spoolss_PrinterInfoArray(r.out.buffer, mem_ctx, r.in.level, r.out.count, &info); - if (!NT_STATUS_IS_OK(status)) { - printf("EnumPrintersArray parse failed - %s\n", nt_errstr(status)); - continue; - } - - for (j=0;j<r.out.count;j++) { - printf("Printer %d\n", j); - NDR_PRINT_UNION_DEBUG(spoolss_PrinterInfo, r.in.level, &info[j]); - } + info = *r.out.info; for (j=0;j<r.out.count;j++) { if (r.in.level == 1) { @@ -943,12 +894,10 @@ static BOOL test_EnumPrinterDrivers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) for (i=0;i<ARRAY_SIZE(levels);i++) { uint32_t buf_size; - char *server; union spoolss_DriverInfo *info; uint32_t j; - asprintf(&server, "\\\\%s", dcerpc_server_name(p)); - r.in.server = server; + r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.environment = "Windows NT x86"; r.in.level = levels[i]; r.in.buffer = NULL; @@ -966,62 +915,42 @@ static BOOL test_EnumPrinterDrivers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) ret = False; continue; } - + if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { DATA_BLOB blob = data_blob_talloc( mem_ctx, NULL, buf_size); data_blob_clear(&blob); r.in.buffer = &blob; - status = dcerpc_spoolss_EnumPrinterDrivers( - p, mem_ctx, &r); + status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r); } if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { printf("EnumPrinterDrivers failed - %s/%s\n", nt_errstr(status), win_errstr(r.out.result)); - goto done; + break; } - if (!r.out.buffer) { + if (!r.out.info) { printf("No printer drivers returned"); - goto done; + break; } - status = pull_spoolss_DriverInfoArray( - r.out.buffer, mem_ctx, r.in.level, r.out.count, &info); + info = *r.out.info; - if (!NT_STATUS_IS_OK(status)) { - printf("EnumPrinterDriverArray parse failed - %s\n", - nt_errstr(status)); - continue; - } + if (r.in.level != 1) continue; for (j=0;j<r.out.count;j++) { - printf("Printer driver %d\n", j); - NDR_PRINT_UNION_DEBUG( - spoolss_DriverInfo, r.in.level, - &info[j]); - - if (r.in.level == 1) { - struct policy_handle handle; + struct policy_handle handle; - if (!call_OpenPrinterEx( - p, mem_ctx, "", - &handle)) - continue; - - test_GetPrinterDriver2( - p, mem_ctx, &handle, - info[j].info1.driver_name); + if (!call_OpenPrinterEx(p, mem_ctx, "",&handle)) { + continue; } + ret &=test_GetPrinterDriver2(p, mem_ctx, &handle, info[j].info1.driver_name); } - - done: - free(server); } - + return ret; } @@ -1032,8 +961,6 @@ BOOL torture_rpc_spoolss(void) TALLOC_CTX *mem_ctx; BOOL ret = True; - mem_ctx = talloc_init("torture_rpc_spoolss"); - status = torture_rpc_connection(&p, DCERPC_SPOOLSS_NAME, DCERPC_SPOOLSS_UUID, @@ -1042,6 +969,8 @@ BOOL torture_rpc_spoolss(void) return False; } + mem_ctx = talloc_init("torture_rpc_spoolss"); + if (!test_EnumPorts(p, mem_ctx)) { ret = False; } @@ -1053,7 +982,7 @@ BOOL torture_rpc_spoolss(void) if (!test_EnumPrinterDrivers(p, mem_ctx)) { ret = False; } - +printf("blub\n"); talloc_free(mem_ctx); torture_rpc_close(p); |