diff options
-rw-r--r-- | source4/librpc/idl/spoolss.idl | 24 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_spoolss_buf.c | 93 |
2 files changed, 93 insertions, 24 deletions
diff --git a/source4/librpc/idl/spoolss.idl b/source4/librpc/idl/spoolss.idl index 2b557d25d2..93efe7805f 100644 --- a/source4/librpc/idl/spoolss.idl +++ b/source4/librpc/idl/spoolss.idl @@ -723,25 +723,25 @@ [default,flag(NDR_REMAINING)] DATA_BLOB data; } spoolss_PrinterData; - [noopnum,nopush,noprint,public] WERROR _spoolss_GetPrinterData( + [noopnum,noprint,public] WERROR _spoolss_GetPrinterData( [in,ref] policy_handle *handle, - [in] unistr value_name, - [in] uint32 offered, - [out] spoolss_PrinterDataType type, - [out] DATA_BLOB data, - [out] uint32 needed + [in] unistr value_name, + [in] uint32 offered, + [out] spoolss_PrinterDataType type, + [out] DATA_BLOB data, + [out] uint32 needed ); - [noopnum,nopush,noprint,public] void __spoolss_GetPrinterData( + [noopnum,noprint,public] void __spoolss_GetPrinterData( [in] spoolss_PrinterDataType type, [out,switch_is(type)] spoolss_PrinterData data ); - [nopull] WERROR spoolss_GetPrinterData( + [nopull,nopush] WERROR spoolss_GetPrinterData( [in,ref] policy_handle *handle, - [in] unistr value_name, - [in] uint32 offered, - [out] spoolss_PrinterDataType type, + [in] unistr value_name, + [in] uint32 offered, + [out] spoolss_PrinterDataType type, [out,subcontext(4),switch_is(type)] spoolss_PrinterData data, - [out] uint32 needed + [out] uint32 needed ); /******************/ diff --git a/source4/librpc/ndr/ndr_spoolss_buf.c b/source4/librpc/ndr/ndr_spoolss_buf.c index 621ddfd081..46b72eaa5f 100644 --- a/source4/librpc/ndr/ndr_spoolss_buf.c +++ b/source4/librpc/ndr/ndr_spoolss_buf.c @@ -26,6 +26,15 @@ #include "librpc/gen_ndr/ndr_spoolss.h" #define NDR_SPOOLSS_PUSH_ENUM_IN(fn) do { \ + if (!r->in.buffer && r->in.offered != 0) {\ + return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\ + "SPOOLSS Buffer: r->in.offered[%u] but there's no buffer",\ + r->in.offered);\ + } else if (r->in.buffer && r->in.buffer->length != r->in.offered) {\ + return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\ + "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of r->in.buffer[%u]",\ + r->in.offered, r->in.buffer->length);\ + }\ _r.in.level = r->in.level;\ _r.in.buffer = r->in.buffer;\ _r.in.offered = r->in.offered;\ @@ -41,19 +50,29 @@ _r.out.needed = r->out.needed;\ _r.out.count = r->out.count;\ _r.out.result = r->out.result;\ - if (r->out.info) {\ - struct __##fn __r;\ + if (r->out.info && !r->in.buffer) {\ + return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\ + "SPOOLSS Buffer: r->out.info but there's no r->in.buffer");\ + }\ + if (r->in.buffer) {\ DATA_BLOB _data_blob_info;\ _ndr_info = ndr_push_init_ctx(ndr);\ if (!_ndr_info) return NT_STATUS_NO_MEMORY;\ _ndr_info->flags= ndr->flags;\ - __r.in.level = r->in.level;\ - __r.in.count = r->out.count;\ - __r.out.info = r->out.info;\ - NDR_CHECK(ndr_push___##fn(_ndr_info, flags, &__r)); \ + if (r->out.info) {\ + struct __##fn __r;\ + __r.in.level = r->in.level;\ + __r.in.count = r->out.count;\ + __r.out.info = r->out.info;\ + NDR_CHECK(ndr_push___##fn(_ndr_info, flags, &__r)); \ + }\ if (r->in.offered > _ndr_info->offset) {\ uint32_t _padding_len = r->in.offered - _ndr_info->offset;\ NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len));\ + } else if (r->in.offered < _ndr_info->offset) {\ + return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\ + "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of out buffer[%u]!",\ + r->in.offered, _ndr_info->offset);\ }\ _data_blob_info = ndr_push_blob(_ndr_info);\ _r.out.info = &_data_blob_info;\ @@ -80,6 +99,15 @@ r->in.buffer = _r.in.buffer;\ r->in.offered = _r.in.offered;\ r->out.needed = _r.out.needed;\ + if (!r->in.buffer && r->in.offered != 0) {\ + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\ + "SPOOLSS Buffer: r->in.offered[%u] but there's no buffer",\ + r->in.offered);\ + } else if (r->in.buffer && r->in.buffer->length != r->in.offered) {\ + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\ + "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of r->in.buffer[%u]",\ + r->in.offered, r->in.buffer->length);\ + }\ } while(0) #define NDR_SPOOLSS_PULL_ENUM_OUT(fn) do { \ @@ -125,11 +153,13 @@ }\ } while(0) -#define _NDR_CHECK_UINT32(call) do { NTSTATUS _status; \ - _status = call; \ - if (!NT_STATUS_IS_OK(_status)) \ - return 0; \ - } while (0) +#define _NDR_CHECK_UINT32(call) do {\ + NTSTATUS _status; \ + _status = call; \ + if (!NT_STATUS_IS_OK(_status)) {\ + return 0; \ + }\ +} while (0) /* TODO: set _ndr_info->flags correct */ #define NDR_SPOOLSS_SIZE_ENUM(fn) do { \ @@ -365,6 +395,43 @@ uint32_t ndr_size_spoolss_EnumPrinterProcessors_info(TALLOC_CTX *mem_ctx, uint32 /* spoolss_GetPrinterData */ +NTSTATUS ndr_push_spoolss_GetPrinterData(struct ndr_push *ndr, int flags, struct spoolss_GetPrinterData *r) +{ + struct _spoolss_GetPrinterData _r; + if (flags & NDR_IN) { + _r.in.handle = r->in.handle; + _r.in.value_name= r->in.value_name; + _r.in.offered = r->in.offered; + NDR_CHECK(ndr_push__spoolss_GetPrinterData(ndr, flags, &_r)); + } + if (flags & NDR_OUT) { + struct ndr_push *_ndr_info;\ + _r.in.handle = r->in.handle; + _r.in.value_name= r->in.value_name; + _r.in.offered = r->in.offered; + _r.out.type = r->out.type; + _r.out.data = data_blob(NULL, 0); + _r.out.needed = r->out.needed; + _r.out.result = r->out.result; + { + struct __spoolss_GetPrinterData __r; + _ndr_info = ndr_push_init_ctx(ndr); + if (!_ndr_info) return NT_STATUS_NO_MEMORY; + _ndr_info->flags= ndr->flags; + __r.in.type = r->out.type; + __r.out.data = r->out.data; + NDR_CHECK(ndr_push___spoolss_GetPrinterData(_ndr_info, flags, &__r)); + if (r->in.offered > _ndr_info->offset) { + uint32_t _padding_len = r->in.offered - _ndr_info->offset; + NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len)); + } + _r.out.data = ndr_push_blob(_ndr_info); + } + NDR_CHECK(ndr_push__spoolss_GetPrinterData(ndr, flags, &_r)); + } + return NT_STATUS_OK; +} + NTSTATUS ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flags, struct spoolss_GetPrinterData *r) { struct _spoolss_GetPrinterData _r; @@ -397,7 +464,9 @@ NTSTATUS ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flags, struct r->out.needed = _r.out.needed; r->out.result = _r.out.result; if (_r.out.data.length != r->in.offered) { - /* TODO: ndr_pull_error(...) */ + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\ + "SPOOLSS Buffer: r->in.offered[%u] doesn't match length of out buffer[%u]",\ + r->in.offered, _r.out.data.length);\ } if (_r.out.data.length > 0 && r->out.needed <= _r.out.data.length) { struct __spoolss_GetPrinterData __r; |