From 9a831a3963d9784a470b7d3971b54bd9bde3d7c3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 6 Jun 2005 09:59:43 +0000 Subject: r7328: fix GetPrinterData and SetPrinterData, with zero length subcontexts metze (This used to be commit 73d597bacf83492ed3da2307dd6785548b903b39) --- source4/include/structs.h | 2 + source4/librpc/idl/spoolss.idl | 32 +++++++++++-- source4/librpc/ndr/ndr_spoolss_buf.c | 91 ++++++++++++++++++++++++++++++++++++ source4/torture/rpc/spoolss.c | 11 +++-- 4 files changed, 127 insertions(+), 9 deletions(-) diff --git a/source4/include/structs.h b/source4/include/structs.h index fbc4150aa3..934dc6e192 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -37,6 +37,8 @@ union spoolss_FormInfo; union spoolss_PortInfo; union spoolss_MonitorInfo; union spoolss_PrintProcessorInfo; +struct spoolss_GetPrinterData; +struct spoolss_SetPrinterData; struct drsuapi_DsReplicaObjectListItem; struct drsuapi_DsReplicaObjectListItemEx; diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl index 9808837422..201226d548 100644 --- a/source4/librpc/idl/spoolss.idl +++ b/source4/librpc/idl/spoolss.idl @@ -652,7 +652,18 @@ [default,flag(NDR_REMAINING)] DATA_BLOB data; } spoolss_PrinterData; - WERROR spoolss_GetPrinterData( + [noopnum,nopush,noprint,public] WERROR _spoolss_GetPrinterData( + [in,ref] policy_handle *handle, + [in] unistr value_name, + [out] spoolss_PrinterDataType type, + [out] DATA_BLOB data, + [in,out,ref] uint32 *buf_size + ); + [noopnum,nopush,noprint,public] void __spoolss_GetPrinterData( + [in] spoolss_PrinterDataType type, + [out,switch_is(type)] spoolss_PrinterData data + ); + [nopull] WERROR spoolss_GetPrinterData( [in,ref] policy_handle *handle, [in] unistr value_name, [out] spoolss_PrinterDataType type, @@ -662,12 +673,23 @@ /******************/ /* Function: 0x1b */ - WERROR spoolss_SetPrinterData( + [noopnum,nopull,noprint,public] WERROR _spoolss_SetPrinterData( [in,ref] policy_handle *handle, [in] unistr value_name, - [in] uint32 type, - [in] DATA_BLOB buffer, - [in] uint32 real_len + [in] spoolss_PrinterDataType type, + [in] DATA_BLOB data, + [in] uint32 _buf_size + ); + [noopnum,nopull,noprint,public] void __spoolss_SetPrinterData( + [in] spoolss_PrinterDataType type, + [out,switch_is(type)] spoolss_PrinterData data + ); + [nopush] WERROR spoolss_SetPrinterData( + [in,ref] policy_handle *handle, + [in] unistr value_name, + [in] spoolss_PrinterDataType type, + [in,subcontext(4),switch_is(type)] spoolss_PrinterData data, + [in,value(ndr_size_spoolss_PrinterData(&r->in.data,r->in.type,flags))] uint32 _buf_size ); /******************/ diff --git a/source4/librpc/ndr/ndr_spoolss_buf.c b/source4/librpc/ndr/ndr_spoolss_buf.c index 26113cca38..97eaaedee4 100644 --- a/source4/librpc/ndr/ndr_spoolss_buf.c +++ b/source4/librpc/ndr/ndr_spoolss_buf.c @@ -350,3 +350,94 @@ uint32_t ndr_size_spoolss_EnumPrinterProcessors_info(TALLOC_CTX *mem_ctx, uint32 { NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrintProcessors); } + +/* + spoolss_GetPrinterData +*/ +NTSTATUS ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flags, struct spoolss_GetPrinterData *r) +{ + struct _spoolss_GetPrinterData _r; + if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + _r.in.handle = r->in.handle; + _r.in.value_name= r->in.value_name; + _r.in.buf_size = r->in.buf_size; + _r.out.type = r->out.type; + _r.out.data = data_blob(NULL,0), + _r.out.buf_size = r->out.buf_size; + NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r)); + r->in.handle = _r.in.handle; + r->in.value_name= _r.in.value_name; + r->in.buf_size = _r.in.buf_size; + } + if (flags & NDR_OUT) { + _r.in.handle = r->in.handle; + _r.in.value_name= r->in.value_name; + _r.in.buf_size = r->in.buf_size; + _r.out.type = r->out.type; + _r.out.data = data_blob(NULL,0), + _r.out.buf_size = r->out.buf_size; + _r.out.result = r->out.result; + NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r)); + r->out.type = _r.out.type; + ZERO_STRUCT(r->out.data); + r->out.buf_size = _r.out.buf_size; + r->out.result = _r.out.result; + if (_r.out.data.length > 0) { + struct __spoolss_GetPrinterData __r; + struct ndr_pull *_ndr_data = ndr_pull_init_blob(&_r.out.data, ndr);\ + if (!_ndr_data) return NT_STATUS_NO_MEMORY;\ + _ndr_data->flags= ndr->flags;\ + __r.in.type = r->out.type; + __r.out.data = r->out.data; + NDR_CHECK(ndr_pull___spoolss_GetPrinterData(_ndr_data, flags, &__r)); + r->out.data = __r.out.data; + } else { + r->out.type = SPOOLSS_PRINTER_DATA_TYPE_NULL; + } + } + return NT_STATUS_OK; +} + +/* + spoolss_SetPrinterData +*/ +NTSTATUS ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, struct spoolss_SetPrinterData *r) +{ + struct _spoolss_SetPrinterData _r; + if (flags & NDR_IN) { + struct ndr_push *_ndr_data; + struct __spoolss_SetPrinterData __r; + DATA_BLOB _data_blob_data; + + _ndr_data = ndr_push_init_ctx(ndr);\ + if (!_ndr_data) return NT_STATUS_NO_MEMORY;\ + _ndr_data->flags= ndr->flags;\ + + __r.in.type = r->in.type; + __r.out.data = r->in.data; + NDR_CHECK(ndr_push___spoolss_SetPrinterData(_ndr_data, NDR_OUT, &__r)); + _data_blob_data = ndr_push_blob(_ndr_data); + + r->in._buf_size = _data_blob_data.length; + + _r.in.handle = r->in.handle; + _r.in.value_name= r->in.value_name; + _r.in.type = r->in.type; + _r.in.data = _data_blob_data; + _r.in._buf_size = r->in._buf_size; + _r.out.result = r->out.result; + NDR_CHECK(ndr_push__spoolss_SetPrinterData(ndr, flags, &_r)); + } + if (flags & NDR_OUT) { + _r.in.handle = r->in.handle; + _r.in.value_name= r->in.value_name; + _r.in.type = r->in.type; + _r.in.data = data_blob(NULL,0), + _r.in._buf_size = r->in._buf_size; + _r.out.result = r->out.result; + NDR_CHECK(ndr_push__spoolss_SetPrinterData(ndr, flags, &_r)); + } + return NT_STATUS_OK; +} diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index b9d48a6da4..7f56212b74 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -1324,9 +1324,8 @@ static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.handle = handle; r.in.value_name = value_name; - r.in.type = 0; - r.in.buffer = data_blob_talloc(mem_ctx, "dog", 4); - r.in.real_len = 4; + r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING; + r.in.data.string = "dog"; printf("Testing SetPrinterData\n"); @@ -1337,6 +1336,10 @@ static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return False; } + if (!test_GetPrinterData(p, mem_ctx, handle, value_name)) { + return False; + } + if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) { return False; } @@ -1828,7 +1831,7 @@ BOOL torture_rpc_spoolss(void) ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "Architecture"); - /*ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");*/ + ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory"); ret &= test_EnumPorts(ctx); -- cgit