mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
ndr: fix push/pull DATA_BLOB with NDR_NOALIGN
This change addresses bug 9026. There are 3 use cases for DATA_BLOB marshalling/unmarshalling: 1) ndr_push_DATA_BLOB and ndr_pull_DATA_BLOB when called with LIBNDR_FLAG_ALIGN* alignment flags set, are used to push/pull padding bytes _only_. The length is determined by the alignment required and the current ndr offset. e.g. dcerpc.idl: typedef struct { ... [flag(NDR_ALIGN8)] DATA_BLOB _pad; } dcerpc_request; 2) When called with the LIBNDR_FLAG_REMAINING flag, all remaining bytes in the ndr buffer are pushed/pulled. e.g. dcerpc.idl: typedef struct { ... [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier; } dcerpc_request; 3) When called without alignment flags, push/pull a uint32 length _and_ a corresponding byte array to/from the ndr buffer. e.g. drsblobs.idl typedef [public] struct { ... DATA_BLOB data; } DsCompressedChunk; The fix for bug 8373 changed the definition of "alignment flags", such that when called with LIBNDR_FLAG_NOALIGN ndr_push/pull_DATA_BLOB behaves as (1: padding bytes) rather than (3: uint32 length + byte array). This breaks marshalling/unmarshalling for the following structures. eventlog.idl: typedef [flag(NDR_NOALIGN|NDR_PAHEX),public] struct { ... DATA_BLOB sid; ... } eventlog_Record_tdb; ntprinting.idl: typedef [flag(NDR_NOALIGN),public] struct { ... DATA_BLOB *nt_dev_private; } ntprinting_devicemode; typedef [flag(NDR_NOALIGN),public] struct { ... DATA_BLOB data; } ntprinting_printer_data; Signed-off-by: Günther Deschner <gd@samba.org>
This commit is contained in:
parent
66514f8bbe
commit
0d3249b927
@ -1247,16 +1247,21 @@ _PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_
|
||||
|
||||
|
||||
/*
|
||||
push a DATA_BLOB onto the wire.
|
||||
*/
|
||||
* Push a DATA_BLOB onto the wire.
|
||||
* 1) When called with LIBNDR_FLAG_ALIGN* alignment flags set, push padding
|
||||
* bytes _only_. The length is determined by the alignment required and the
|
||||
* current ndr offset.
|
||||
* 2) When called with the LIBNDR_FLAG_REMAINING flag, push the byte array to
|
||||
* the ndr buffer.
|
||||
* 3) Otherwise, push a uint32 length _and_ a corresponding byte array to the
|
||||
* ndr buffer.
|
||||
*/
|
||||
_PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, DATA_BLOB blob)
|
||||
{
|
||||
if (ndr->flags & LIBNDR_FLAG_REMAINING) {
|
||||
/* nothing to do */
|
||||
} else if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
|
||||
if (ndr->flags & LIBNDR_FLAG_NOALIGN) {
|
||||
blob.length = 0;
|
||||
} else if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
|
||||
} else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
|
||||
if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
|
||||
blob.length = NDR_ALIGN(ndr, 2);
|
||||
} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
|
||||
blob.length = NDR_ALIGN(ndr, 4);
|
||||
@ -1273,18 +1278,23 @@ _PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flag
|
||||
}
|
||||
|
||||
/*
|
||||
pull a DATA_BLOB from the wire.
|
||||
*/
|
||||
* Pull a DATA_BLOB from the wire.
|
||||
* 1) when called with LIBNDR_FLAG_ALIGN* alignment flags set, pull padding
|
||||
* bytes _only_. The length is determined by the alignment required and the
|
||||
* current ndr offset.
|
||||
* 2) When called with the LIBNDR_FLAG_REMAINING flag, pull all remaining bytes
|
||||
* from the ndr buffer.
|
||||
* 3) Otherwise, pull a uint32 length _and_ a corresponding byte array from the
|
||||
* ndr buffer.
|
||||
*/
|
||||
_PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
|
||||
{
|
||||
uint32_t length = 0;
|
||||
|
||||
if (ndr->flags & LIBNDR_FLAG_REMAINING) {
|
||||
length = ndr->data_size - ndr->offset;
|
||||
} else if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
|
||||
if (ndr->flags & LIBNDR_FLAG_NOALIGN) {
|
||||
length = 0;
|
||||
} else if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
|
||||
} else if (ndr->flags & (LIBNDR_ALIGN_FLAGS & ~LIBNDR_FLAG_NOALIGN)) {
|
||||
if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
|
||||
length = NDR_ALIGN(ndr, 2);
|
||||
} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
|
||||
length = NDR_ALIGN(ndr, 4);
|
||||
|
Loading…
x
Reference in New Issue
Block a user