The branch, master has been updated via 5f60855... samba-spoolss: use spoolss_StringArray2 in spoolss_EnumPrinterKey. via 292af4f... spoolss: add spoolss_StringArray2. via 91bb065... s3-spoolss: move MAXDEVICENAME to spoolss idl. from 53744f0... s3: Cope with older external libtdb
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 5f60855ba2eb822dcb867378ff09278c42931b89 Author: Günther Deschner <g...@samba.org> Date: Wed Dec 2 14:25:31 2009 +0100 samba-spoolss: use spoolss_StringArray2 in spoolss_EnumPrinterKey. This should finally resolve the endian issues we were seeing on sparc and is much cleaner for spoolss clients and servers. Guenther commit 292af4fc046ff39ebd3ec853c402dc267a863fa6 Author: Günther Deschner <g...@samba.org> Date: Wed Dec 2 14:22:52 2009 +0100 spoolss: add spoolss_StringArray2. The difference to spoolss_StringArray is that in spoolss_StringArray2 the string array is put into a subcontext of _ndr_size. Guenther commit 91bb0659776d397bc4b8ca7a534f6f2327e2e6fe Author: Günther Deschner <g...@samba.org> Date: Tue Dec 1 02:38:19 2009 +0100 s3-spoolss: move MAXDEVICENAME to spoolss idl. Guenther ----------------------------------------------------------------------- Summary of changes: librpc/gen_ndr/cli_spoolss.c | 8 +- librpc/gen_ndr/cli_spoolss.h | 4 +- librpc/gen_ndr/ndr_spoolss.c | 104 +++++++++++++++++++++++------------ librpc/gen_ndr/ndr_spoolss.h | 3 + librpc/gen_ndr/spoolss.h | 8 ++- librpc/gen_ndr/srv_spoolss.c | 4 +- librpc/idl/spoolss.idl | 13 +++- librpc/ndr/ndr_spoolss_buf.c | 9 +++ librpc/ndr/ndr_spoolss_buf.h | 1 + source3/include/nt_printing.h | 2 - source3/rpc_client/cli_spoolss.c | 24 +------- source3/rpc_server/srv_spoolss_nt.c | 2 +- source4/torture/rpc/spoolss.c | 19 +----- source4/torture/rpc/spoolss_win.c | 19 +----- 14 files changed, 118 insertions(+), 102 deletions(-) Changeset truncated at 500 lines: diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c index aba70f2..0a5c2a6 100644 --- a/librpc/gen_ndr/cli_spoolss.c +++ b/librpc/gen_ndr/cli_spoolss.c @@ -12207,7 +12207,7 @@ struct tevent_req *rpccli_spoolss_EnumPrinterKey_send(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, struct policy_handle *_handle /* [in] [ref] */, const char *_key_name /* [in] [charset(UTF16)] */, - uint16_t *_key_buffer /* [out] [ref,size_is(offered/2)] */, + struct spoolss_StringArray2 *_key_buffer /* [out] [ref] */, uint32_t _offered /* [in] */, uint32_t *_needed /* [out] [ref] */) { @@ -12278,7 +12278,7 @@ static void rpccli_spoolss_EnumPrinterKey_done(struct tevent_req *subreq) } /* Copy out parameters */ - memcpy(state->orig.out.key_buffer, state->tmp.out.key_buffer, (state->tmp.in.offered / 2) * sizeof(*state->orig.out.key_buffer)); + *state->orig.out.key_buffer = *state->tmp.out.key_buffer; *state->orig.out.needed = *state->tmp.out.needed; /* Copy result */ @@ -12317,7 +12317,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, const char *key_name /* [in] [charset(UTF16)] */, - uint16_t *key_buffer /* [out] [ref,size_is(offered/2)] */, + struct spoolss_StringArray2 *key_buffer /* [out] [ref] */, uint32_t offered /* [in] */, uint32_t *needed /* [out] [ref] */, WERROR *werror) @@ -12345,7 +12345,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, } /* Return variables */ - memcpy(key_buffer, r.out.key_buffer, (r.in.offered / 2) * sizeof(*key_buffer)); + *key_buffer = *r.out.key_buffer; *needed = *r.out.needed; /* Return result */ diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h index 943cbce..58a45ee 100644 --- a/librpc/gen_ndr/cli_spoolss.h +++ b/librpc/gen_ndr/cli_spoolss.h @@ -1262,7 +1262,7 @@ struct tevent_req *rpccli_spoolss_EnumPrinterKey_send(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, struct policy_handle *_handle /* [in] [ref] */, const char *_key_name /* [in] [charset(UTF16)] */, - uint16_t *_key_buffer /* [out] [ref,size_is(offered/2)] */, + struct spoolss_StringArray2 *_key_buffer /* [out] [ref] */, uint32_t _offered /* [in] */, uint32_t *_needed /* [out] [ref] */); NTSTATUS rpccli_spoolss_EnumPrinterKey_recv(struct tevent_req *req, @@ -1272,7 +1272,7 @@ NTSTATUS rpccli_spoolss_EnumPrinterKey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, const char *key_name /* [in] [charset(UTF16)] */, - uint16_t *key_buffer /* [out] [ref,size_is(offered/2)] */, + struct spoolss_StringArray2 *key_buffer /* [out] [ref] */, uint32_t offered /* [in] */, uint32_t *needed /* [out] [ref] */, WERROR *werror); diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index a578ed8..41d07d1 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -1051,7 +1051,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DeviceMode(struct ndr_push *ndr, int { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->devicename, 32, sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->devicename, MAXDEVICENAME, sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_push_spoolss_DeviceModeSpecVersion(ndr, NDR_SCALARS, r->specversion)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->driverversion)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->size)); @@ -1070,7 +1070,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DeviceMode(struct ndr_push *ndr, int NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->yresolution)); NDR_CHECK(ndr_push_spoolss_DeviceModeTTOption(ndr, NDR_SCALARS, r->ttoption)); NDR_CHECK(ndr_push_spoolss_DeviceModeCollate(ndr, NDR_SCALARS, r->collate)); - NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->formname, 32, sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->formname, MAXDEVICENAME, sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->logpixels)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->bitsperpel)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->pelswidth)); @@ -1107,7 +1107,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DeviceMode(struct ndr_pull *ndr, int { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->devicename, 32, sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->devicename, MAXDEVICENAME, sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_pull_spoolss_DeviceModeSpecVersion(ndr, NDR_SCALARS, &r->specversion)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->driverversion)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); @@ -1126,7 +1126,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DeviceMode(struct ndr_pull *ndr, int NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->yresolution)); NDR_CHECK(ndr_pull_spoolss_DeviceModeTTOption(ndr, NDR_SCALARS, &r->ttoption)); NDR_CHECK(ndr_pull_spoolss_DeviceModeCollate(ndr, NDR_SCALARS, &r->collate)); - NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->formname, 32, sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->formname, MAXDEVICENAME, sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->logpixels)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->bitsperpel)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->pelswidth)); @@ -8125,6 +8125,61 @@ _PUBLIC_ void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *n ndr->depth--; } +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2)); + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + { + struct ndr_push *_ndr_string; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_string, 0, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2 * 2)); + NDR_CHECK(ndr_push_string_array(_ndr_string, NDR_SCALARS, r->string)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_string, 0, (ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2 * 2)); + } + ndr->flags = _flags_save_string_array; + } + NDR_CHECK(ndr_push_trailer_align(ndr, 4)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + { + struct ndr_pull *_ndr_string; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_string, 0, r->_ndr_size * 2)); + NDR_CHECK(ndr_pull_string_array(_ndr_string, NDR_SCALARS, &r->string)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_string, 0, r->_ndr_size * 2)); + } + ndr->flags = _flags_save_string_array; + } + NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_StringArray2(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray2 *r) +{ + ndr_print_struct(ndr, name, "spoolss_StringArray2"); + ndr->depth++; + ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?(ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags) - 4) / 2:r->_ndr_size); + ndr_print_string_array(ndr, "string", r->string); + ndr->depth--; +} + static enum ndr_err_code ndr_push_spoolss_AddDriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_AddDriverInfo1 *r) { if (ndr_flags & NDR_SCALARS) { @@ -28072,7 +28127,6 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterDataEx(struct ndr_print *ndr, const c _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterKey *r) { - uint32_t cntr_key_buffer_1; if (flags & NDR_IN) { if (r->in.handle == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -28088,10 +28142,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, if (r->out.key_buffer == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, r->in.offered / 2)); - for (cntr_key_buffer_1 = 0; cntr_key_buffer_1 < r->in.offered / 2; cntr_key_buffer_1++) { - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->out.key_buffer[cntr_key_buffer_1])); - } + NDR_CHECK(ndr_push_spoolss_StringArray2(ndr, NDR_SCALARS, r->out.key_buffer)); if (r->out.needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } @@ -28103,9 +28154,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_EnumPrinterKey(struct ndr_push *ndr, _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterKey *r) { - uint32_t cntr_key_buffer_1; TALLOC_CTX *_mem_save_handle_0; - TALLOC_CTX *_mem_save_key_buffer_1; + TALLOC_CTX *_mem_save_key_buffer_0; TALLOC_CTX *_mem_save_needed_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -28125,22 +28175,19 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.key_name, ndr_get_array_length(ndr, &r->in.key_name), sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offered)); - NDR_PULL_ALLOC_N(ndr, r->out.key_buffer, r->in.offered / 2); - memset(r->out.key_buffer, 0, (r->in.offered / 2) * sizeof(*r->out.key_buffer)); + NDR_PULL_ALLOC(ndr, r->out.key_buffer); + ZERO_STRUCTP(r->out.key_buffer); NDR_PULL_ALLOC(ndr, r->out.needed); ZERO_STRUCTP(r->out.needed); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_pull_array_size(ndr, &r->out.key_buffer)); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC_N(ndr, r->out.key_buffer, ndr_get_array_size(ndr, &r->out.key_buffer)); - } - _mem_save_key_buffer_1 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.key_buffer, 0); - for (cntr_key_buffer_1 = 0; cntr_key_buffer_1 < r->in.offered / 2; cntr_key_buffer_1++) { - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->out.key_buffer[cntr_key_buffer_1])); + NDR_PULL_ALLOC(ndr, r->out.key_buffer); } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_1, 0); + _mem_save_key_buffer_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.key_buffer, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_spoolss_StringArray2(ndr, NDR_SCALARS, r->out.key_buffer)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_key_buffer_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.needed); } @@ -28149,16 +28196,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_EnumPrinterKey(struct ndr_pull *ndr, NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.needed)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_needed_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); - if (r->out.key_buffer) { - NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.key_buffer, r->in.offered / 2)); - } } return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_EnumPrinterKey *r) { - uint32_t cntr_key_buffer_1; ndr_print_struct(ndr, name, "spoolss_EnumPrinterKey"); ndr->depth++; if (flags & NDR_SET_VALUES) { @@ -28180,16 +28223,7 @@ _PUBLIC_ void ndr_print_spoolss_EnumPrinterKey(struct ndr_print *ndr, const char ndr->depth++; ndr_print_ptr(ndr, "key_buffer", r->out.key_buffer); ndr->depth++; - ndr->print(ndr, "%s: ARRAY(%d)", "key_buffer", (int)r->in.offered / 2); - ndr->depth++; - for (cntr_key_buffer_1=0;cntr_key_buffer_1<r->in.offered / 2;cntr_key_buffer_1++) { - char *idx_1=NULL; - if (asprintf(&idx_1, "[%d]", cntr_key_buffer_1) != -1) { - ndr_print_uint16(ndr, "key_buffer", r->out.key_buffer[cntr_key_buffer_1]); - free(idx_1); - } - } - ndr->depth--; + ndr_print_spoolss_StringArray2(ndr, "key_buffer", r->out.key_buffer); ndr->depth--; ndr_print_ptr(ndr, "needed", r->out.needed); ndr->depth++; diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index 185f825..895e1e9 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -345,6 +345,9 @@ void ndr_print_spoolss_SetPrinterInfoCtr(struct ndr_print *ndr, const char *name enum ndr_err_code ndr_push_spoolss_StringArray(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray *r); enum ndr_err_code ndr_pull_spoolss_StringArray(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray *r); void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray *r); +enum ndr_err_code ndr_push_spoolss_StringArray2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_StringArray2 *r); +enum ndr_err_code ndr_pull_spoolss_StringArray2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray2 *r); +void ndr_print_spoolss_StringArray2(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray2 *r); void ndr_print_spoolss_AddDriverInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo1 *r); enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r); enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index a4c0010..8b9a1ee 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -12,6 +12,7 @@ #define PRINTER_STATUS_OK ( 0x00000000 ) #define JOB_STATUS_QUEUED ( 0x0000 ) +#define MAXDEVICENAME ( 32 ) #define PRINTER_ENUM_ICONMASK ( (PRINTER_ENUM_ICON1|PRINTER_ENUM_ICON2|PRINTER_ENUM_ICON3|PRINTER_ENUM_ICON4|PRINTER_ENUM_ICON5|PRINTER_ENUM_ICON6|PRINTER_ENUM_ICON7|PRINTER_ENUM_ICON8) ) #define SPL_ARCH_WIN40 ( "WIN40" ) #define SPL_ARCH_W32X86 ( "W32X86" ) @@ -1205,6 +1206,11 @@ struct spoolss_StringArray { const char ** string;/* [flag(LIBNDR_FLAG_STR_NULLTERM)] */ }/* [public] */; +struct spoolss_StringArray2 { + uint32_t _ndr_size;/* [value((ndr_size_spoolss_StringArray2(r,ndr->iconv_convenience,ndr->flags)-4)/2)] */ + const char ** string;/* [subcontext_size(_ndr_size*2),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */ +}/* [public] */; + struct spoolss_AddDriverInfo1 { const char *driver_name;/* [unique,charset(UTF16)] */ }; @@ -3551,7 +3557,7 @@ struct spoolss_EnumPrinterKey { } in; struct { - uint16_t *key_buffer;/* [ref,size_is(offered/2)] */ + struct spoolss_StringArray2 *key_buffer;/* [ref] */ uint32_t *needed;/* [ref] */ WERROR result; } out; diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c index 6ca334b..3b981f0 100644 --- a/librpc/gen_ndr/srv_spoolss.c +++ b/librpc/gen_ndr/srv_spoolss.c @@ -6325,7 +6325,7 @@ static bool api_spoolss_EnumPrinterKey(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.key_buffer = talloc_zero_array(r, uint16_t, r->in.offered / 2); + r->out.key_buffer = talloc_zero(r, struct spoolss_StringArray2); if (r->out.key_buffer == NULL) { talloc_free(r); return false; @@ -9504,7 +9504,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_SPOOLSS_ENUMPRINTERKEY: { struct spoolss_EnumPrinterKey *r = (struct spoolss_EnumPrinterKey *)_r; ZERO_STRUCT(r->out); - r->out.key_buffer = talloc_zero_array(mem_ctx, uint16_t, r->in.offered / 2); + r->out.key_buffer = talloc_zero(mem_ctx, struct spoolss_StringArray2); if (r->out.key_buffer == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index bb517a1..3ae1685 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -368,8 +368,10 @@ import "misc.idl", "security.idl", "winreg.idl"; DMDITHER_GRAYSCALE = 0x0000000A } spoolss_DeviceModeDitherType; + const int MAXDEVICENAME = 32; + typedef [public,gensize] struct { - [charset(UTF16)] uint16 devicename[32]; + [charset(UTF16)] uint16 devicename[MAXDEVICENAME]; spoolss_DeviceModeSpecVersion specversion; uint16 driverversion; uint16 size; @@ -388,7 +390,7 @@ import "misc.idl", "security.idl", "winreg.idl"; uint16 yresolution; spoolss_DeviceModeTTOption ttoption; spoolss_DeviceModeCollate collate; - [charset(UTF16)] uint16 formname[32]; + [charset(UTF16)] uint16 formname[MAXDEVICENAME]; uint16 logpixels; /* reserved */ uint32 bitsperpel; /* reserved */ uint32 pelswidth; /* reserved */ @@ -978,6 +980,11 @@ import "misc.idl", "security.idl", "winreg.idl"; /*[subcontext(0),subcontext_size(_ndr_size*2)]*/ nstring_array string; } spoolss_StringArray; + typedef [public] struct { + [value((ndr_size_spoolss_StringArray2(r, ndr->iconv_convenience, ndr->flags)-4)/2)] uint32 _ndr_size; + [subcontext(0),subcontext_size(_ndr_size*2)] nstring_array string; + } spoolss_StringArray2; + typedef struct { [string,charset(UTF16)] uint16 *driver_name; } spoolss_AddDriverInfo1; @@ -2576,7 +2583,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [public] WERROR spoolss_EnumPrinterKey( [in, ref] policy_handle *handle, [in] [string,charset(UTF16)] uint16 key_name[], - [out,ref] [size_is(offered/2)] uint16 *key_buffer, + [out,ref] spoolss_StringArray2 *key_buffer, [in] uint32 offered, [out,ref] uint32 *needed ); diff --git a/librpc/ndr/ndr_spoolss_buf.c b/librpc/ndr/ndr_spoolss_buf.c index 0acae3d..9968e90 100644 --- a/librpc/ndr/ndr_spoolss_buf.c +++ b/librpc/ndr/ndr_spoolss_buf.c @@ -708,6 +708,15 @@ _PUBLIC_ size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); } +_PUBLIC_ size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags) +{ + if (!r) { + return 4; + } + + return ndr_size_struct((const struct spoolss_StringArray *)r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); +} + /* hand marshall as pidl cannot (yet) generate a relative pointer to a fixed array of * structs */ diff --git a/librpc/ndr/ndr_spoolss_buf.h b/librpc/ndr/ndr_spoolss_buf.h index aa6e277..9a76f82 100644 --- a/librpc/ndr/ndr_spoolss_buf.h +++ b/librpc/ndr/ndr_spoolss_buf.h @@ -47,6 +47,7 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r); uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, struct smb_iconv_convenience *ic, uint32_t flags); size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r, struct smb_iconv_convenience *ic, int flags); +size_t ndr_size_spoolss_StringArray2(const struct spoolss_StringArray2 *r, struct smb_iconv_convenience *ic, int flags); _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); void ndr_print_spoolss_Field(struct ndr_print *ndr, const char *name, const union spoolss_Field *r); diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index 3a509a2..713443a 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -36,8 +36,6 @@ typedef struct { NT_PRINTER_KEY *keys; } NT_PRINTER_DATA; -#define MAXDEVICENAME 32 - typedef struct ntdevicemode { fstring devicename; diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index a4622d0..047cb70 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -810,44 +810,28 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, NTSTATUS status; WERROR werror; uint32_t needed; - uint16_t *buffer = NULL; - - *key_buffer = NULL; - - if (offered) { - buffer = talloc_array(mem_ctx, uint16_t, offered/2); - W_ERROR_HAVE_NO_MEMORY(buffer); - } + struct spoolss_StringArray2 _key_buffer; status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, handle, key_name, - buffer, + &_key_buffer, offered, &needed, &werror); if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { offered = needed; - buffer = talloc_realloc(mem_ctx, buffer, uint16_t, needed/2); - W_ERROR_HAVE_NO_MEMORY(buffer); status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, handle, key_name, - buffer, + &_key_buffer, offered, &needed, &werror); } - if (W_ERROR_IS_OK(werror)) { - const char **array; - DATA_BLOB blob = data_blob_const((uint8_t *)buffer, offered); - if (!pull_reg_multi_sz(mem_ctx, &blob, &array)) { - return WERR_NOMEM; - } - *key_buffer = array; - } + *key_buffer = _key_buffer.string; return werror; } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index d742048..4a3f07f 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -9157,7 +9157,7 @@ WERROR _spoolss_EnumPrinterKey(pipes_struct *p, result = WERR_MORE_DATA; } else { result = WERR_OK; - memcpy(r->out.key_buffer, blob.data, blob.length); + r->out.key_buffer->string = array; } done: diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 396ed75..e341b71 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -3043,44 +3043,31 @@ bool test_printer_keys(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) { - DATA_BLOB blob; const char **key_array = NULL; int i; { struct spoolss_EnumPrinterKey r; -- Samba Shared Repository